home *** CD-ROM | disk | FTP | other *** search
/ Aminet 1 (Walnut Creek) / Aminet - June 1993 [Walnut Creek].iso / usenet / sources / volume2 / graphics / surf_1.of < prev    next >
Text File  |  1988-10-21  |  66KB  |  2,926 lines

  1. Path: xanth!mcnc!rutgers!mailrus!ames!ll-xn!adelie!infinet!ulowell!page
  2. From: page@swan.ulowell.edu (Bob Page)
  3. Newsgroups: comp.sources.amiga
  4. Subject: v02i002:  surf - produce bezier surfaces of revolution, Part01/03
  5. Message-ID: <9732@swan.ulowell.edu>
  6. Date: 20 Oct 88 01:31:30 GMT
  7. Organization: University of Lowell, Computer Science Dept.
  8. Lines: 2915
  9. Approved: page@swan.ulowell.edu
  10.  
  11. Submitted-by: edavies@uvvm.bitnet (Eric Davies)
  12. Posting-number: Volume 2, Issue 2
  13. Archive-name: graphics/surf.1of3
  14.  
  15. Surf is a program for producing bezier surfaces of revolution.  It
  16. produces awesome pictures of wine glasses and doorknobs, and other
  17. objects one could turn on a lathe.  Surf includes the capacity to map
  18. iff image files onto any surface that it can draw.
  19.  
  20. # This is a shell archive.  Remove anything before this line
  21. # then unpack it by saving it in a file and typing "sh file"
  22. # (Files unpacked will be owned by you and have default permissions).
  23. # This archive contains the following files:
  24. #    ./menudef.c
  25. #    ./menudef.h
  26. #    ./menuexp.h
  27. #    ./mergergb.c
  28. #    ./mergergb.lnk
  29. #    ./mouse.c
  30. #    ./mytypes.h
  31. #    ./packer.c
  32. #    ./poly.c
  33. #    ./poly.h
  34. #    ./readilbm.c
  35. #    ./readilbm.h
  36. #    ./revolve.c
  37. #    ./revolve.h
  38. #    ./scrndef.c
  39. #    ./scrndef.h
  40. #    ./scrnio.c
  41. #    ./scrnio.h
  42. #    ./scrnio.ih
  43. #    ./scrnops.c
  44. #    ./surf.lnk
  45. #    ./writeilbm.c
  46. #
  47. if `test ! -s ./menudef.c`
  48. then
  49. echo "writing ./menudef.c"
  50. cat > ./menudef.c << '\Rogue\Monster\'
  51. #include <exec/types.h>
  52. #include <exec/memory.h>
  53. #include <intuition/intuition.h>
  54. #include <graphics/gfxmacros.h>
  55. #ifdef MANX
  56. #include <functions.h>
  57. #endif
  58. #include "scrnio.h"
  59. #include "menudef.h"
  60.  
  61. #include "scrndef.h"
  62. #include "poly.h"
  63. #include "readilbm.h"
  64.  
  65. #define Selected(ax) ((ax).Flags & CHECKED)
  66.  
  67. #include "menu_color.c"
  68. #include "menu_scrn.c"
  69. #include "menu_image.c"
  70. #include "menu_files.c"
  71.  
  72. struct Menu menu[] ={
  73.     { &menu[1], /* next menu */
  74.     8, 0, /* x, y */
  75.     6*8, 10, /* w,h */
  76.     MENUENABLED,
  77.     (BYTE *)"File",
  78.     fileitems,
  79.     0,0,0,0
  80.     },
  81.     { &menu[2], /* next menu */
  82.     7*8, 0, /* x, y */
  83.     6*8, 10, /* w,h */
  84.     MENUENABLED,
  85.     (BYTE *)"Color",
  86.     coloritems,
  87.     0,0,0,0
  88.     },
  89.     { &menu[3], /* next menu */
  90.     14*8,0, /* x, y */
  91.     7*8, 10, /* w,h */
  92.     MENUENABLED,
  93.     (BYTE *)"Screen",
  94.     scrnitems,
  95.     0,0,0,0
  96.     },
  97.     { NULL, /* next menu */
  98.     22*8,0, /* x, y */
  99.     6*8, 10, /* w,h */
  100.     MENUENABLED,
  101.     (BYTE *)"Image",
  102.     imageitems,
  103.     0,0,0,0
  104.     }
  105. };
  106.  
  107.  
  108.  
  109. void MenuHandler(code)
  110. USHORT code;
  111. {
  112.     if( code == 0xffff ) { /* invalid menu pick */
  113.         return;
  114.     }
  115.  
  116.     switch( MENUNUM(code)) {
  117.         case 0: /* write ilbm */
  118.             MenuDoFile(ITEMNUM(code));
  119.             break;
  120.         case 1: /* set screen color */
  121.             MenuSetColMap();
  122.             break;
  123.         case 2: /* set screen type */
  124.             MenuSetScrn();
  125.             break;
  126.         case 3: /* set image stuff */
  127.             MenuSetImage();
  128.             break;
  129.         default:
  130.             break;
  131.     }
  132. }
  133. \Rogue\Monster\
  134. else
  135.   echo "will not over write ./menudef.c"
  136. fi
  137. if `test ! -s ./menudef.h`
  138. then
  139. echo "writing ./menudef.h"
  140. cat > ./menudef.h << '\Rogue\Monster\'
  141. extern struct Menu menu[];
  142. extern void MenuHandler(/* USHORT */);
  143.  
  144. \Rogue\Monster\
  145. else
  146.   echo "will not over write ./menudef.h"
  147. fi
  148. if `test ! -s ./menuexp.h`
  149. then
  150. echo "writing ./menuexp.h"
  151. cat > ./menuexp.h << '\Rogue\Monster\'
  152. #ifndef MENUEXP_H_FILE
  153. #define MENUEXP_H_FILE
  154.  
  155. #ifndef INTUITION_INTUITION_H
  156. #include <intuition/intuition.h>
  157. #endif  INTUITION_INTUITION_H
  158.  
  159.  
  160. extern USHORT *AbortDrawPtr;
  161. extern USHORT *DebugOnPtr;
  162.  
  163. #define AbortDraw (*AbortDrawPtr & CHECKED)
  164. #define ClrAbort() { *AbortDrawPtr &= ~CHECKED; }
  165. #define DebugOn (*DebugOnPtr & CHECKED)
  166.  
  167. #endif MENUEXP_H_FILE
  168. \Rogue\Monster\
  169. else
  170.   echo "will not over write ./menuexp.h"
  171. fi
  172. if `test ! -s ./mergergb.c`
  173. then
  174. echo "writing ./mergergb.c"
  175. cat > ./mergergb.c << '\Rogue\Monster\'
  176. /*
  177.  * This program, when called with arg "smith", tries to read smith.r, smith.g
  178.  * and smith.b, and write a combined raw data file acceptable to RAY2, called
  179.  * smith.tmp
  180.  */
  181. #include <stdio.h>
  182. #include "mytypes.h"
  183.  
  184. #define RED 0
  185. #define GRN 1
  186. #define BLU 2
  187. #define NumPrims 3 /* number of primary colors */
  188.  
  189. #define MakeID(a,b,c,d) ( ((a)<<24) | ((b)<<16) | ((c)<<8) | (d) )
  190.  
  191. #define ID_FORM MakeID('F','O','R','M')
  192. #define ID_ILBM MakeID('I','L','B','M')
  193. #define ID_BMHD MakeID('B','M','H','D')
  194. #define ID_CMAP MakeID('C','M','A','P')
  195. #define ID_CAMG MakeID('C','A','M','G')
  196. #define ID_BODY MakeID('B','O','D','Y')
  197.  
  198. #define ROUNDUP(x) ( ((x)+1) & (~1L) )
  199.  
  200. struct CHUNK {
  201.     unsigned long Id, Size;
  202. } Chunk;
  203.  
  204. struct BMHD {
  205.     short w,h,x,y;
  206.     char npl,mask,compress,pad1;
  207.     short transparentColor;
  208.     char xAspect,yAspect;
  209.     short pageWidth,pageHeight;
  210. };
  211.  
  212. /*
  213.  * compare width and height of two bit maps
  214.  * return false if equal
  215.  */
  216. bool CmpBMHD(a, b)
  217.     struct BMHD *a, *b;
  218. {
  219.     return( a->w != b->w ||
  220.             a->h != b->h ||
  221.           a->npl != b->npl
  222.           );
  223. }
  224.  
  225.  
  226. struct BMHD bmhd[NumPrims];
  227. static FILE *ftrip[NumPrims], *fout;
  228. char *nametrip[NumPrims];
  229. char *oname;
  230. bool FileError;
  231. short depth;
  232.  
  233. unsigned char colmap[NumPrims][32][3];
  234.  
  235.  
  236. /*
  237.  * read len bytes from selected file
  238.  */
  239. void FRead(buffer, len, filenum)
  240.     char *buffer;
  241.     int len, filenum;
  242. {
  243.     if( fread(buffer, len, 1, ftrip[filenum]) == 0 ) {
  244.         fprintf(stderr, "read error in %s\n", nametrip[filenum] );
  245.         exit(-1);
  246.     }
  247. }
  248.  
  249.  
  250.  
  251. #define ABORT(str) { fprintf(stderr,str); exit(-1); }
  252.  
  253. #define ReadChunk()  FRead(&Chunk, sizeof(Chunk), filenum)
  254.  
  255. void ReadIffHeaders(filenum)
  256.     int filenum;
  257. {
  258.     long    ILBMid;
  259.     bool cmapFlag = false,
  260.          bmhdFlag = false;
  261.     short i;
  262.  
  263.  
  264.     ReadChunk ();
  265.     if (Chunk.Id != ID_FORM)
  266.         ABORT ("Not an IFF File");
  267.  
  268.     FRead (&ILBMid, 4, filenum);
  269.     if (ILBMid != ID_ILBM)
  270.         ABORT ("Not an ILBM File");
  271.  
  272.     while (1) {
  273.         long camgdata;
  274.  
  275.         ReadChunk ();
  276.  
  277.         if (Chunk.Id == ID_BODY) {
  278.             if (!cmapFlag) {
  279.                 printf("no cmap before body in %s\n", nametrip[filenum]);
  280.                 FileError = true;
  281.             }
  282.             if (!bmhdFlag) {
  283.                 printf("no bmhd before the body in %s\n", nametrip[filenum]);
  284.                 FileError = true;
  285.             }
  286.             return;
  287.         }
  288.  
  289.         if( feof( ftrip[filenum] ) ) {
  290.             printf("reached end of file without seeing body in %s\n", nametrip[filenum]);
  291.             FileError = true;
  292.             return;
  293.         }
  294.  
  295.         switch (Chunk.Id) {
  296.             case ID_CMAP:
  297.                 FRead (colmap[filenum], Chunk.Size, filenum);
  298.                 for (i = 0; i < 32; i++) {
  299.                     colmap[filenum][i][filenum] >>= 4;
  300.                 }
  301.                 cmapFlag = true;
  302.                 break;
  303.             case ID_BMHD:
  304.                 FRead(&bmhd[filenum], Chunk.Size, filenum);
  305.                 bmhdFlag = true;
  306.                 break;
  307.             case ID_CAMG:
  308.                 FRead( &camgdata, sizeof(camgdata),filenum );
  309.                 break;
  310.             default:            /* unknown identifier */
  311.                 fseek( ftrip[filenum], Chunk.Size, 1);
  312.                 break;
  313.         }
  314.     }
  315. }
  316.  
  317.  
  318. /*
  319.  * leftmost pixel of byte is in most significant bit of byte
  320.  */
  321. static char GetIlbmVal( rastlist, h)
  322.     char *rastlist[6];
  323.     int h;
  324. {
  325.     int i;
  326.     char value = 0;
  327.     short mask, bytep;
  328.  
  329.     mask = 0x80 >> ( h & 7);
  330.     bytep = h >> 3;
  331.  
  332.     for( i = depth-1; i >= 0; i-- ) {
  333.         value <<= 1;
  334.         value |= (*(rastlist[i]+bytep) & mask) ? 1: 0;
  335.     }
  336.     return( value );
  337. }
  338.  
  339. /*
  340.  * decompress a runlength row of bytes
  341.  */
  342. static void ReadDecomLine(linebytes, rp, filenum)
  343.     int linebytes, filenum;
  344.     char *rp;
  345. {
  346.     int runlen;
  347.     char pixel;
  348.  
  349.     while (linebytes) {
  350.         runlen = getc (ftrip[filenum]);
  351.         if (runlen > 127)
  352.             runlen -= 256;
  353.         if (runlen >= 0) {
  354.             runlen++;
  355.             FRead (rp, runlen, filenum);
  356.             rp += runlen;
  357.             linebytes -= runlen;
  358.         }
  359.         else {
  360.             runlen = -runlen + 1;
  361.             linebytes -= runlen;
  362.             pixel = getc (ftrip[filenum]);
  363.             do
  364.                 *(rp++) = pixel;
  365.             while (--runlen);
  366.         }
  367.     }
  368. }
  369. /*
  370.  * read raster line from one of the color files
  371.  */
  372. void LoadRaster(raster, ByteWidth, filenum)
  373.     char *raster[6];
  374.     int ByteWidth, filenum;
  375. {
  376.     if(bmhd[filenum].compress = 0) {
  377.         FRead (raster, ByteWidth * depth, filenum);
  378.     }
  379.     else {
  380.         short i;
  381.         for( i = 0; i < depth; i++) {
  382.             ReadDecomLine( ByteWidth, raster[i], filenum);
  383.         }
  384.     }
  385. }
  386.  
  387. /*
  388.  * write intensity values for a given gun
  389.  * note: I've made dirty assumption about byte ordering in a short word
  390.  * if you run this on an ibm (ha ha ha) you'll have to change it
  391.  */
  392. #define ChipSize 4
  393. void SaveRaster( raster, width, prim)
  394.     char *raster[];
  395.     int width, prim;
  396. {
  397.     short i, j;
  398.     unsigned short val;
  399.  
  400.     for( i = 0; i < width; i += ChipSize ) {
  401.         val = colmap[prim][GetIlbmVal(raster, i+3)][prim] << ChipSize;
  402.         val |= colmap[prim][GetIlbmVal(raster, i+2)][prim];
  403.         fputc( val&0xff, fout);
  404.         val = colmap[prim][GetIlbmVal(raster, i+1)][prim] << ChipSize;
  405.         val |= colmap[prim][GetIlbmVal(raster, i+0)][prim];
  406.         fputc( val&0xff, fout);
  407.     }
  408. }
  409.  
  410. /*
  411.  * translate body of file to format RAY2 likes
  412.  */
  413. void TranslateRay2Body()
  414. {
  415.     int BytesWidth;
  416.     int row, height, width, plane, prim;
  417.     char *raster[6];
  418.  
  419.     depth = bmhd[0].npl;
  420.     width = bmhd[0].w;
  421.     height = bmhd[0].h;
  422.     BytesWidth = (width + 7)/8 ;
  423.  
  424.     for( plane = 0; plane < bmhd[0].npl; plane++ ) {
  425.         raster[plane] = (char *)malloc(BytesWidth);
  426.     }
  427.  
  428.     for( row = 0; !FileError && row < height; row++ ) {
  429.         fputc((unsigned char)(row>>8),fout);      /* write line number */
  430.         fputc((unsigned char)(row&0xff),fout);
  431.  
  432.         for( prim = RED; prim <= BLU; prim++ ) {
  433.             LoadRaster( raster, BytesWidth, prim);
  434.             SaveRaster( raster, width, prim);
  435.         }
  436.     }
  437. }
  438.  
  439.  
  440.  
  441. main(argc, argv)
  442.     int argc;
  443.     char *argv[];
  444. {
  445.     char buff[4][80];
  446.     char *extensions = "rgb";
  447.     int i;
  448.  
  449.     if( argc == 1 || *argv[1] == '?' ) {
  450.         fprintf(stderr,"usage:  merge filename\n");
  451.         exit(-1);
  452.     }
  453.     FileError = false;
  454.  
  455.     for( i = 0; i < NumPrims; i++ ) {
  456.         sprintf(buff[i], "%s.%c", argv[1], extensions[i]);
  457.         nametrip[i] = buff[i];
  458.         ftrip[i] = fopen(nametrip[i],"r");
  459.         if(!ftrip[i]) {
  460.             fprintf(stderr,"unable to read %s\n", nametrip[i]);
  461.             FileError = true;
  462.         }
  463.     }
  464.  
  465.     sprintf(buff[3], "%s.tmp", argv[1]);
  466.     oname = (argc>2)? argv[2]: buff[3];
  467.     fout = fopen( oname,"w");
  468.     if(!fout) {
  469.         fprintf(stderr,"unable to write to %s\n", oname);
  470.         FileError = true;
  471.     }
  472.  
  473.     if( FileError ) goto ErrorExit;
  474.  
  475.     for( i = 0; i < NumPrims; i++ ) {
  476.         printf("reading header %d\n", i);
  477.         ReadIffHeaders(i);
  478.     }
  479.  
  480.     for( i = 1; i < NumPrims; i++ ) {
  481.         if( CmpBMHD(&bmhd[0], &bmhd[i])) {
  482.             fprintf(stderr,"image sizes differ(r != %d)\n", i);
  483.             FileError = true;
  484.         }
  485.     }
  486.  
  487.     if( FileError ) goto ErrorExit;
  488.     printf("about to translate body\n");
  489.     TranslateRay2Body();
  490.  
  491.     ErrorExit:
  492.         for( i = 0; i < NumPrims; i++) {
  493.             if(ftrip[i]) fclose( ftrip[i] );
  494.         }
  495.         if(fout) fclose(fout);
  496. }
  497.  
  498.  
  499. \Rogue\Monster\
  500. else
  501.   echo "will not over write ./mergergb.c"
  502. fi
  503. if `test ! -s ./mergergb.lnk`
  504. then
  505. echo "writing ./mergergb.lnk"
  506. cat > ./mergergb.lnk << '\Rogue\Monster\'
  507. ROOT     lib:c.o
  508.     MergeRGB.o
  509.  
  510. LIBRARY    LIB:lc.lib
  511.     Lib:lcm.lib
  512.     LIB:amiga.lib
  513.  
  514. TO MergeRGB
  515.  
  516. verbose
  517. nodebug
  518. \Rogue\Monster\
  519. else
  520.   echo "will not over write ./mergergb.lnk"
  521. fi
  522. if `test ! -s ./mouse.c`
  523. then
  524. echo "writing ./mouse.c"
  525. cat > ./mouse.c << '\Rogue\Monster\'
  526. #include "scrnio.ih"
  527. #ifdef MANX
  528. #include <functions.h>
  529. #endif
  530. #include "scrnio.h"
  531. #include "mytypes.h"
  532.  
  533. #include "bezpt.h"
  534. #include "control.h"
  535.  
  536.  
  537. static bool buttondown;  /* is left button down */
  538. static short mousex, mousey;
  539. static bool isleftbut;  /* left button or pseudo middle button */
  540.  
  541. void HandleTicks(mesg)
  542. struct IntuiMessage *mesg;
  543. {
  544.     int x, y;
  545.  
  546.     x = CntrX(mesg->MouseX);
  547.     y = CntrY(mesg->MouseY);
  548.  
  549.     if(!buttondown || (mousex == x && mousey == y )){
  550.         return;
  551.     }
  552.  
  553.     mousex = x;
  554.     mousey = y;
  555.  
  556.     switch( CurMode ) {
  557.  
  558.     case DRAWPOLY:
  559.          EditBezPt( mousex, mousey);
  560.          break;
  561.  
  562.     case FITBEZIER:
  563.         /*
  564.          * need to select between the two
  565.          */
  566.         if( isleftbut ) {
  567.             EditControl0(mousex, mousey);
  568.         }
  569.         else {
  570.             EditControl1(mousex, mousey);
  571.         }
  572.         break;
  573.  
  574.     default:
  575.         break;
  576.     }
  577. }
  578.  
  579.  
  580.  
  581. void HandleMButtons(mesg)
  582. struct IntuiMessage *mesg;
  583. {
  584.  
  585.     long leftdist, rightdist;
  586.     long tx, ty;
  587.  
  588.     mousex = CntrX(mesg->MouseX);
  589.     mousey = CntrY(mesg->MouseY);
  590.  
  591.     switch( mesg->Code) {
  592.     case SELECTDOWN:
  593.         buttondown = true;  /* down */
  594.  
  595.         switch( CurMode ) {
  596.         case DRAWPOLY:
  597.             InitBezPt( mousex, mousey);
  598.             if( GetNumSegs() == 0 ) {
  599.                 InitBezPt( mousex, mousey );
  600.             }
  601.             break;
  602.  
  603.         case FITBEZIER:
  604.             tx = mousex - Cntrl1X(GetCurSeg());
  605.             ty = mousey - Cntrl1Y(GetCurSeg());
  606.             leftdist = tx *tx + ty * ty;
  607.  
  608.             tx = mousex - Cntrl2X(GetCurSeg());
  609.             ty = mousey - Cntrl2Y(GetCurSeg());
  610.             rightdist = tx *tx + ty * ty;
  611.  
  612.             if( isleftbut = (leftdist <= rightdist) ) {
  613.                 EditControl0( mousex, mousey );
  614.             }
  615.             else {
  616.                 EditControl1( mousex, mousey );
  617.             }
  618.             break;
  619.  
  620.         default:
  621.             break;
  622.         }
  623.         break;
  624.  
  625.  
  626.     case SELECTUP:
  627.         buttondown = false; /* up */
  628.         break;
  629.  
  630.     case MENUUP:
  631.         if( CurMode == FITBEZIER ) {
  632.             DrawControl0();
  633.             DrawControl1();
  634.             NextSeg();
  635.             DrawControl0();
  636.             DrawControl1();
  637.         }
  638.         break;
  639.  
  640.     default:
  641.         break;
  642.     }
  643. }
  644. \Rogue\Monster\
  645. else
  646.   echo "will not over write ./mouse.c"
  647. fi
  648. if `test ! -s ./mytypes.h`
  649. then
  650. echo "writing ./mytypes.h"
  651. cat > ./mytypes.h << '\Rogue\Monster\'
  652. #ifndef MYTYPES_H_FILE
  653. #define MYTYPES_H_FILE
  654. #define true 1
  655. #define false 0
  656.  
  657. typedef char bool;
  658. extern char *calloc(), *malloc();
  659.  
  660. #define null 0L
  661.  
  662. #ifndef MANX
  663. #include "exec/types.h"
  664. #include "libraries/mathffp.h"
  665. #define ceil    SPCeil
  666. #define floor    SPFloor
  667. #define fabs    SPAbs
  668. #endif
  669.  
  670.  
  671. #endif MYTYPES_H_FILE
  672. \Rogue\Monster\
  673. else
  674.   echo "will not over write ./mytypes.h"
  675. fi
  676. if `test ! -s ./packer.c`
  677. then
  678. echo "writing ./packer.c"
  679. cat > ./packer.c << '\Rogue\Monster\'
  680. /*
  681.  * this file is a hacked up version of the original, who blurb is below
  682.  * changes made: internal buffer no longer static, but is now on stack
  683.  */
  684. /*----------------------------------------------------------------------*
  685.  * packer.c Convert data to "cmpByteRun1" run compression.     11/15/85
  686.  *
  687.  * By Jerry Morrison and Steve Shaw, Electronic Arts.
  688.  * This software is in the public domain.
  689.  *
  690.  *      control bytes:
  691.  *       [0..127]   : followed by n+1 bytes of data.
  692.  *       [-1..-127] : followed by byte to be repeated (-n)+1 times.
  693.  *       -128       : NOOP.
  694.  *
  695.  * This version for the Commodore-Amiga computer.
  696.  *----------------------------------------------------------------------*/
  697. #include <exec/types.h>
  698.  
  699. #define DUMP    0
  700. #define RUN     1
  701.  
  702. #define MinRun 3
  703. #define MaxRun 128
  704. #define MaxDat 128
  705.  
  706. static short putSize;
  707. #define GetByte()       (*source++)
  708. #define PutByte(c)      { *dest++ = c;   ++putSize; }
  709.  
  710. static BYTE *buf;  /* [TBD] should be 128?  on stack?*/
  711.  
  712. static BYTE *PutDump(dest, nn)
  713.     BYTE *dest;
  714.     int nn;
  715. {
  716.         int i;
  717.  
  718.     PutByte(nn-1);
  719.     for(i = 0;  i < nn;  i++)   PutByte(buf[i]);
  720.     return(dest);
  721. }
  722.  
  723. static BYTE *PutRun(dest, nn, cc)
  724.     BYTE *dest;
  725.     int nn, cc;
  726. {
  727.     PutByte(-(nn-1));
  728.     PutByte(cc);
  729.     return(dest);
  730. }
  731.  
  732. #define OutDump(nn)   dest = PutDump(dest, nn)
  733. #define OutRun(nn,cc) dest = PutRun(dest, nn, cc)
  734.  
  735. /*----------- PackRow --------------------------------------------------*/
  736. /* Given POINTERS TO POINTERS, packs one row, updating the source and
  737.    destination pointers.  RETURNs count of packed bytes.*/
  738. int PackRow(source, dest, rowSize)
  739.     BYTE *source, *dest;
  740.     int rowSize;
  741. {
  742.     char innerbuf[256];
  743.     char c,lastc = '\0';
  744.     BOOL mode = DUMP;
  745.     short nbuf = 0;             /* number of chars in buffer */
  746.     short rstart = 0;           /* buffer index current run starts */
  747.  
  748.     /*
  749.      * cute way to make local buffer known to external procedures
  750.      * since static variables increase executable size in Manx
  751.      */
  752.     buf = innerbuf; /* way to put make local buffer known to external procs */
  753.     putSize = 0;
  754.     buf[0] = lastc = c = GetByte();  /* so have valid lastc */
  755.     nbuf = 1;   rowSize--;      /* since one byte eaten.*/
  756.  
  757.  
  758.     for (;  rowSize;  --rowSize) {
  759.         buf[nbuf++] = c = GetByte();
  760.         switch (mode) {
  761.                 case DUMP:
  762.                         /* If the buffer is full, write the length byte,
  763.                            then the data */
  764.                         if (nbuf>MaxDat) {
  765.                                 OutDump(nbuf-1);
  766.                                 buf[0] = c;
  767.                                 nbuf = 1;   rstart = 0;
  768.                                 break;
  769.                                 }
  770.  
  771.                         if (c == lastc) {
  772.                             if (nbuf-rstart >= MinRun) {
  773.                                 if (rstart > 0) OutDump(rstart);
  774.                                 mode = RUN;
  775.                                 }
  776.                             else if (rstart == 0)
  777.                                 mode = RUN;     /* no dump in progress,
  778.                                 so can't lose by making these 2 a run.*/
  779.                             }
  780.                         else  rstart = nbuf-1;          /* first of run */
  781.                         break;
  782.  
  783.                 case RUN: if ( (c != lastc)|| ( nbuf-rstart > MaxRun)) {
  784.                         /* output run */
  785.                         OutRun(nbuf-1-rstart,lastc);
  786.                         buf[0] = c;
  787.                         nbuf = 1; rstart = 0;
  788.                         mode = DUMP;
  789.                         }
  790.                         break;
  791.                 }
  792.  
  793.         lastc = c;
  794.         }
  795.  
  796.     switch (mode) {
  797.         case DUMP: OutDump(nbuf); break;
  798.         case RUN: OutRun(nbuf-rstart,lastc); break;
  799.         }
  800.     return(putSize);
  801. }
  802.  
  803. \Rogue\Monster\
  804. else
  805.   echo "will not over write ./packer.c"
  806. fi
  807. if `test ! -s ./poly.c`
  808. then
  809. echo "writing ./poly.c"
  810. cat > ./poly.c << '\Rogue\Monster\'
  811. #include <math.h>
  812. #include "mytypes.h"
  813. #include "scrnio.h"
  814. #include "bezpt.h"
  815. #include "revolve.h"
  816. #include "control.h"
  817. #include "poly.h"
  818. #include "readilbm.h"
  819. #include "menuexp.h"
  820.  
  821. bool  SpecOn = false; /* specular lighting enable - default off */
  822.  
  823. float Ambience = DefAmbience;
  824. float PtIntensity = (float)DefIntensity;
  825. float Kd = DefKd,
  826.       Ks = DefKs;
  827.  
  828. Pt3 LightSrc = {
  829.         DefLightSrcX,
  830.         DefLightSrcY,
  831.         DefLightSrcZ
  832.         };
  833.  
  834. static
  835. Rhomboid *polylist = null,
  836.          *nextpoly;
  837.  
  838. MapRhomboid *mpolylist = null,
  839.         *mnextpoly;
  840.  
  841. static
  842. int polyspace = 0;
  843.  
  844.  
  845. static bool shadeflag;
  846.  
  847. long CalcMaxPolyNum() {
  848.     return( GetNumSegs() * BezMesh * RevMesh );
  849. }
  850.  
  851. static
  852. bool PrepPoly()
  853. {
  854.         if( polylist ) free( (char *)polylist );
  855.         polylist = (Rhomboid *)malloc( CalcMaxPolyNum() * sizeof(Rhomboid));
  856.         if( !polylist ) {
  857.             OutErr("PrepPoly: not enough memory");
  858.             return( true );
  859.         }
  860.         nextpoly = polylist;
  861.         return(false); /* success = 0 */
  862. }
  863.  
  864.  
  865. static bool
  866. PrepMPoly()
  867. {
  868.         if( mpolylist ) free( (char *)mpolylist );
  869.         mpolylist = (MapRhomboid *)
  870.                     malloc( CalcMaxPolyNum() * sizeof(MapRhomboid));
  871.         if( !mpolylist ) {
  872.             OutErr("PrepPoly: not enough memory");
  873.             return( true );
  874.         }
  875.         mnextpoly = mpolylist;
  876.         return(false); /* success = 0 */
  877. }
  878.  
  879.  
  880. /*
  881.  * Multiply a vector by scalar quantity
  882.  */
  883. void ScaleVec( fact, src, dst )
  884.         float fact;
  885.         Pt3 *src, *dst;
  886. {
  887.         dst->x = src->x * fact;
  888.         dst->y = src->y * fact;
  889.         dst->z = src->z * fact;
  890. }
  891. /*
  892.  * convert a vector to a unitized vector
  893.  * if possible
  894.  */
  895. void Unitize( vec )
  896.         Pt3 *vec;
  897. {
  898.         float len;
  899.  
  900.         len = vec->x*vec->x + vec->y*vec->y + vec->z*vec->z;
  901.         len = sqrt( len );
  902.         if( len != 0.0 ) {
  903.                 vec->x /= len;
  904.                 vec->y /= len;
  905.                 vec->z /= len;
  906.         }
  907. }
  908.  
  909. /*
  910.  * calculate a vector from two points
  911.  */
  912. void CalcVector( src1, src2, dest )
  913. Pt3 *src1, *src2, *dest ;
  914. {
  915.         dest->x = src1->x - src2->x;
  916.         dest->y = src1->y - src2->y;
  917.         dest->z = src1->z - src2->z;
  918. }
  919.  
  920.  
  921.  
  922.  
  923. /*
  924.  * calculate a normal from a list of polygons. This routine does the
  925.  * logical trick of trying to exclude each point in turn if the
  926.  * normal can not be calculated, or something of the sort.
  927.  * a value of true is returned if a normal with a nonzero z component
  928.  * could not be calculated
  929.  */
  930.  
  931. bool CalcNormal( vxlist, normal)
  932.         PtGen *vxlist[];
  933.         register Pt3 *normal;
  934. {
  935.         int i, k, m;
  936.         Pt3 *j[3];
  937.         Pt3 v1, v2;
  938.  
  939.         for( i = 0; i < RhomVxNum; i++ ) {
  940.                 for( k = 0, m = 3; m--; k++ ) {
  941.                         if( k == i ) {
  942.                                 k++;
  943.                         }
  944.                         j[m] = &vxlist[k]->d3;
  945.                 }
  946.                 CalcVector( j[1], j[0], &v1 );
  947.                 CalcVector( j[2], j[1], &v2 );
  948.  
  949.                 normal->z = v1.x*v2.y - v1.y*v2.x;
  950.                 if( normal->z == 0 ) {
  951.                         continue;
  952.                 }
  953.                 normal->x = v1.y*v2.z - v1.z*v2.y;
  954.                 normal->y = v1.z*v2.x - v1.x*v2.z;
  955.                 if( normal->z < 0 ) {
  956.                         normal->x = -normal->x;
  957.                         normal->y = -normal->y;
  958.                         normal->z = -normal->z;
  959.                 }
  960.                 Unitize(normal);
  961.                 return( false );
  962.         }
  963.         return(true);
  964. }
  965.  
  966.  
  967. /*
  968.  * Euclidean dot product.
  969.  * I wonder what the minkowski dot product would look like
  970.  */
  971. float DotProd( v1, v2 )
  972.         Pt3 *v1, *v2;
  973. {
  974.         return( v1->x*v2->x + v1->y*v2->y + v1->z*v2->z );
  975. }
  976.  
  977.  
  978.  
  979.  
  980.  
  981. /*
  982.  * define a polygon as a set of four points
  983.  * returns true if polygon created
  984.  */
  985. static bool CreatePoly(curpoly, p0, p1, p2, p3)
  986.     register Rhomboid *curpoly;
  987.     PtGen *p0, *p1, *p2, *p3;
  988. {
  989.  
  990.     Pt3 normal;
  991.     PtGen *list[RhomVxNum];
  992.  
  993.     list[0] = p0; list[1] = p1; list[2] = p2; list[3] = p3;
  994.     /*
  995.      * compute stuff needed only if producing shaded image
  996.      */
  997.     if( shadeflag ) {
  998.             Pt3 lvec;
  999.             Pt3 center;
  1000.             float ptintens;
  1001.             float ldotn; /* light vector dot normal */
  1002.             /*
  1003.             * if cant compute normal, then junk polygon
  1004.             */
  1005.             if( CalcNormal( list, &normal )) {
  1006.                 return(false);
  1007.             }
  1008.  
  1009.             curpoly->intensity = Ambience;
  1010.             center.x = ( list[0]->d3.x
  1011.                     + list[1]->d3.x
  1012.                     + list[2]->d3.x
  1013.                     + list[3]->d3.x)/4.0;
  1014.             center.y = ( list[0]->d3.y
  1015.                     + list[1]->d3.y
  1016.                     + list[2]->d3.y
  1017.                     + list[3]->d3.y)/4.0;
  1018.             center.z = ( list[0]->d3.z
  1019.                     + list[1]->d3.z
  1020.                     + list[2]->d3.z
  1021.                     + list[3]->d3.z)/4.0;
  1022.  
  1023.             curpoly->depth = center.z;
  1024.  
  1025.             CalcVector( ¢er, &LightSrc, &lvec );
  1026.             Unitize( &lvec );
  1027.             ldotn = DotProd( &lvec, &normal );
  1028.             if( ldotn < 0 ) {
  1029.                 ptintens = PtIntensity * Kd * -ldotn;
  1030.                 curpoly->intensity += ptintens;
  1031.             }
  1032.             /*
  1033.              * calculate specular component
  1034.              */
  1035.             if( SpecOn && ldotn < 0 ) {
  1036.                 float Kspec, Is;
  1037.                 Pt3 rvec; /* lvec reflected through poly */
  1038.  
  1039.                 ScaleVec( 2*ldotn, &normal, &rvec );
  1040.                 CalcVector(&lvec, &rvec, &rvec );
  1041.                 Unitize( ¢er );
  1042.                 Kspec = DotProd( &rvec, ¢er);
  1043.  
  1044.                 if( Kspec <= 0.0 ) {
  1045.                     Is = Ks * Kspec * Kspec* PtIntensity;
  1046.                     curpoly->intensity += Is;
  1047.                 }
  1048.             }
  1049.  
  1050.             if( curpoly->intensity > 1.0 ) {
  1051.                 curpoly->intensity = 1.0;
  1052.             }
  1053.     }
  1054.     else {
  1055.         /*
  1056.          * calculate depth of polygon
  1057.          * for now, try an average of the vertex depths
  1058.          */
  1059.         curpoly->depth =( list[0]->d3.z
  1060.                 + list[1]->d3.z
  1061.                 + list[2]->d3.z
  1062.                 + list[3]->d3.z)/4.0;
  1063.     }
  1064.     /*
  1065.      * store index to screen coordinates
  1066.      */
  1067.     curpoly->pt[0] = p0->d2;
  1068.     curpoly->pt[1] = p1->d2;
  1069.     curpoly->pt[2] = p2->d2;
  1070.     curpoly->pt[3] = p3->d2;
  1071.  
  1072.     return(true);
  1073. }
  1074. /*
  1075.  * passable procedure for creating polygons without mapping
  1076.  */
  1077. static
  1078. void AcceptPoly(p0, p1, p2, p3)
  1079.     PtGen *p0, *p1, *p2, *p3;
  1080. {
  1081.     if( CreatePoly(nextpoly, p0, p1, p2,p3)) {
  1082.         nextpoly++;
  1083.     }
  1084. }
  1085.  
  1086. static
  1087. void AcceptMPoly( p0, p1, p2, p3)
  1088.     PtGen *p0, *p1, *p2, *p3;
  1089. {
  1090.     if( CreatePoly(&mnextpoly->rhom, p0, p1, p2,p3)) {
  1091.         mnextpoly->bezindex = RevImageB;
  1092.         mnextpoly->revindex = RevImageR;
  1093.         mnextpoly++;
  1094.     }
  1095. }
  1096.  
  1097.  
  1098.  
  1099.  
  1100.  
  1101. /*
  1102.  * compare the depth of two polygons for SortPoly
  1103.  */
  1104. static int CmpDepth( a, b )
  1105.         Rhomboid *a, *b;
  1106. {
  1107.         if( a->depth < b->depth ) return(-1);
  1108.         else if( a->depth > b->depth ) return(1);
  1109.         else return(0);
  1110. }
  1111.  
  1112. static int CmpMDepth( a, b )
  1113.         MapRhomboid *a, *b;
  1114. {
  1115.         if( a->rhom.depth < b->rhom.depth ) return(-1);
  1116.         else if( a->rhom.depth > b->rhom.depth ) return(1);
  1117.         else return(0);
  1118. }
  1119.  
  1120.  
  1121.  
  1122.  
  1123.  
  1124. void RevNoShade() {
  1125.         Rhomboid *i;
  1126.         if( GetNumSegs() < 1 ) {
  1127.                 return;
  1128.         }
  1129.         CurMode = NOTACTIVE;
  1130.  
  1131.         ClrAbort();
  1132.         shadeflag = false;
  1133.         if( PrepPoly() ) return;
  1134.         if( Revolve(AcceptPoly) ) return;
  1135.  
  1136.         qsort( (char *)polylist, nextpoly - polylist,
  1137.                 sizeof(Rhomboid), CmpDepth);
  1138.  
  1139.         ClrWindow(false);
  1140.  
  1141.         for( i = polylist; i< nextpoly; i++ ) {
  1142.             if( AbortDraw ) return;
  1143.                 DrawRhomFrame( i->pt );
  1144.         }
  1145. }
  1146.  
  1147.  
  1148.  
  1149.  
  1150. void RevShade() {
  1151.         register Rhomboid *i;
  1152.  
  1153.         if( GetNumSegs() < 1 ) {
  1154.                 return;
  1155.         }
  1156.         CurMode = NOTACTIVE;
  1157.         ClrAbort();
  1158.         shadeflag = true;
  1159.         if( PrepPoly() || Revolve(AcceptPoly) ) {
  1160.             return;
  1161.         }
  1162.         qsort( (char *)polylist, nextpoly-polylist,
  1163.                 sizeof(Rhomboid), CmpDepth);
  1164.  
  1165.         ClrWindow(false);
  1166.  
  1167.         for( i = polylist; i< nextpoly; i++ ) {
  1168.                 if( AbortDraw ) return;
  1169.                 DrawRhomShade( i );
  1170.         }
  1171. }
  1172.  
  1173.  
  1174.  
  1175. void RevMap() {
  1176.     register MapRhomboid *i;
  1177.  
  1178.     if( GetNumSegs() < 1 ) {
  1179.             return;
  1180.     }
  1181.     if( InitMapping() ) {
  1182.         return;
  1183.     }
  1184.     ClrAbort();
  1185.     CurMode = NOTACTIVE;
  1186.     shadeflag = true;
  1187.  
  1188.  
  1189.     if( PrepMPoly() || Revolve(AcceptMPoly) ) {
  1190.         return;
  1191.     }
  1192.     qsort( (char *)mpolylist, mnextpoly-mpolylist,
  1193.         sizeof(MapRhomboid), CmpMDepth);
  1194.     ClrWindow(false);
  1195.  
  1196.     for( i = mpolylist; i< mnextpoly; i++ ) {
  1197.             if( AbortDraw ) return;
  1198.             DrawRhomMap(i);
  1199.     }
  1200. }
  1201. \Rogue\Monster\
  1202. else
  1203.   echo "will not over write ./poly.c"
  1204. fi
  1205. if `test ! -s ./poly.h`
  1206. then
  1207. echo "writing ./poly.h"
  1208. cat > ./poly.h << '\Rogue\Monster\'
  1209. #ifndef POLY_H_FILE
  1210. #define POLY_H_FILE
  1211. #include <exec/types.h>
  1212. #include "mytypes.h"
  1213. #include "revolve.h"
  1214.  
  1215.  
  1216. #define RhomVxNum 4
  1217.  
  1218. typedef struct {
  1219.     ScrnPair    pt[RhomVxNum];
  1220.     float       depth;
  1221.     float       intensity;
  1222. } Rhomboid;
  1223.  
  1224. typedef struct {
  1225.     Rhomboid   rhom;
  1226.     short   bezindex,
  1227.             revindex;
  1228. } MapRhomboid;
  1229.  
  1230. extern bool SpecOn;
  1231.  
  1232. #define DefLightSrcX 0.0
  1233. #define DefLightSrcY 0.0
  1234. #define DefLightSrcZ 0.0
  1235. #define DefIntensity 0.8
  1236. #define DefAmbience 0.15
  1237. #define DefKd   0.8
  1238. #define DefKs   0.2
  1239.  
  1240.  
  1241. extern float Ambience,
  1242.              PtIntensity,
  1243.              Kd, Ks;
  1244.  
  1245. extern Pt3 LightSrc;
  1246.  
  1247. extern void RevNoShade();
  1248. extern void RevShade();
  1249. extern void RevMap();
  1250.  
  1251. #endif !POLY_H_FILE
  1252. \Rogue\Monster\
  1253. else
  1254.   echo "will not over write ./poly.h"
  1255. fi
  1256. if `test ! -s ./readilbm.c`
  1257. then
  1258. echo "writing ./readilbm.c"
  1259. cat > ./readilbm.c << '\Rogue\Monster\'
  1260. #include <stdio.h>
  1261. #include <ctype.h>
  1262. #include "readilbm.h"
  1263.  
  1264. #define FALSE 0
  1265. #define TRUE 1
  1266.  
  1267. #define RED 0
  1268. #define GRN 1
  1269. #define BLU 2
  1270.  
  1271.  /* color to grey conversion methods */
  1272.  
  1273. #define AVERAGE 0
  1274. #define LUMIN    1
  1275. #define DIST     2
  1276. #define REDONLY  3
  1277. #define GREENONLY 4
  1278. #define BLUEONLY 5
  1279.  
  1280. #define MakeID(a,b,c,d) ( ((a)<<24) | ((b)<<16) | ((c)<<8) | (d) )
  1281.  
  1282. #define ID_FORM MakeID('F','O','R','M')
  1283. #define ID_ILBM MakeID('I','L','B','M')
  1284. #define ID_BMHD MakeID('B','M','H','D')
  1285. #define ID_CMAP MakeID('C','M','A','P')
  1286. #define ID_CAMG MakeID('C','A','M','G')
  1287. #define ID_BODY MakeID('B','O','D','Y')
  1288.  
  1289. #define ROUNDUP(x) ( ((x)+1) & (~1L) )
  1290.  
  1291.  
  1292.  
  1293. static struct CHUNK {
  1294.     unsigned long Id, Size;
  1295. } Chunk;
  1296.  
  1297. static unsigned char   cmap[32][3];
  1298.  
  1299. struct BMHD {
  1300.     short w,h,x,y;
  1301.     char npl,mask,compress,pad1;
  1302.     short transparentColor;
  1303.     char xAspect,yAspect;
  1304.     short pageWidth,pageHeight;
  1305. };
  1306.  
  1307.  
  1308. static short    Color[32],              /* output colors        */
  1309.                 Method = AVERAGE;       /* color conversion     */
  1310. static short     numcolors;
  1311.  
  1312. static
  1313. FILE            *fin;                   /* input file           */
  1314.  
  1315. extern char     *malloc();
  1316.  
  1317. static void FRead();
  1318. static void ReadBMHD();
  1319. static void ReadChunk();
  1320. static void RastOut();
  1321. static void HamOut();
  1322. static char GetIlbmVal();
  1323. static void InitColorMappings();
  1324. static short Convert();
  1325. static void ReadDecomLine();
  1326. static void ProcessRows();
  1327.  
  1328. #define ABORT(str) { OutErr(str); goto ErrorExit; }
  1329.  
  1330.  
  1331. void SetGreyModel( model )
  1332.     int model;
  1333. {
  1334.     Method = model;
  1335. }
  1336.  
  1337.  /*
  1338.   * main routine for reading in an iff file
  1339.   */
  1340.  
  1341. void ReadIlbm(filename)
  1342.     char *filename;
  1343. {
  1344.     struct BMHD bmhd;
  1345.     long    ILBMid;
  1346.     unsigned char cmapFlag = FALSE,
  1347.                   bmhdFlag = FALSE;
  1348.  
  1349.  
  1350.     if ((fin = fopen (filename, "r")) == NULL) {
  1351.         OutErr ("ERROR: cannot open input file");
  1352.         return;
  1353.     }
  1354.     /* read in iff file */
  1355.  
  1356.     ReadChunk ();
  1357.     if (Chunk.Id != ID_FORM)
  1358.         ABORT ("Not an IFF File");
  1359.  
  1360.     FRead (&ILBMid, 4);
  1361.     if (ILBMid != ID_ILBM)
  1362.         ABORT ("Not an ILBM File");
  1363.  
  1364.     while (1) {
  1365.         long camgdata;
  1366.  
  1367.         ReadChunk ();
  1368.  
  1369.         if (Chunk.Id == ID_BODY)
  1370.             break;
  1371.  
  1372.         if( feof( fin ) ) {
  1373.             ABORT("reached end of file without seeing body\n");
  1374.         }
  1375.  
  1376.         switch (Chunk.Id) {
  1377.             case ID_CMAP:
  1378.                 FRead (cmap, Chunk.Size);
  1379.                 numcolors = Chunk.Size/3;
  1380.                 cmapFlag = TRUE;
  1381.                 break;
  1382.             case ID_BMHD:
  1383.                 ReadBMHD (&bmhd);
  1384.                 bmhdFlag = TRUE;
  1385.                 break;
  1386.             case ID_CAMG:
  1387.                 FRead( &camgdata, sizeof(camgdata) );
  1388.                 break;
  1389.             default:            /* unknown identifier */
  1390.                 fseek( fin, Chunk.Size, 1);
  1391.                 break;
  1392.         }
  1393.     }
  1394.     if (!cmapFlag) {
  1395.         ABORT("IFF file does not contain a CMAP chunk before the BODY\n");
  1396.     }
  1397.  
  1398.     if (!bmhdFlag) {
  1399.         ABORT("IFF file does not contain a BMHD chunk before the BODY\n");
  1400.     }
  1401.  
  1402.     InitColorMappings();
  1403.     if( OpenImgPix( bmhd.w, bmhd.h, Convert(0xf, 0xf, 0xf)) ) {
  1404.         ProcessRows(&bmhd);
  1405.     }
  1406.  
  1407.     ErrorExit:
  1408.         fclose( fin);
  1409. }
  1410.  
  1411. static void ProcessRows(bmhd)
  1412.     struct BMHD *bmhd;
  1413. {
  1414.     char *rastlist[6];
  1415.     char *Raster;
  1416.     int depth, i, v, pixwidth;
  1417.     int BytePerLine;
  1418.  
  1419.     depth = bmhd->npl;
  1420.     pixwidth = bmhd->w;
  1421.     BytePerLine =(pixwidth+7) / 8;
  1422.  
  1423.  
  1424.     Raster = (char *) malloc (BytePerLine * depth);
  1425.  
  1426.     if(!Raster ) {
  1427.         OutErr("ProcessRows:could not allocate Raster");
  1428.         return;
  1429.     }
  1430.  
  1431.     for( i = 0; i < depth; i++ ) {
  1432.         rastlist[i] = Raster + BytePerLine*i;
  1433.     }
  1434.  
  1435.     for( v = 0; v < bmhd->h; v++) {
  1436.         switch (bmhd->compress) {
  1437.             case 0:
  1438.                 FRead (Raster, BytePerLine * depth);
  1439.                 break;
  1440.             case 1:
  1441.                 for( i = 0; i < depth; i++) {
  1442.                     ReadDecomLine( BytePerLine, rastlist[i]);
  1443.                 }
  1444.                 break;
  1445.             default:
  1446.                 ABORT ("Unknown Compression type in BODY");
  1447.  
  1448.         }
  1449.         if(depth == 6 ) {
  1450.             HamOut( rastlist, pixwidth, v);
  1451.         }
  1452.         else {
  1453.             RastOut( rastlist, pixwidth, v, depth);
  1454.         }
  1455.     }
  1456.  
  1457.     ErrorExit:
  1458.         if( Raster ) free(Raster);
  1459. }
  1460.  
  1461.  
  1462. static void ReadDecomLine(linebytes, rp)
  1463.     int linebytes;
  1464.     char *rp;
  1465. {
  1466.     int runlen;
  1467.     char pixel;
  1468.  
  1469.     while (linebytes) {
  1470.         runlen = getc (fin);
  1471.         if (runlen > 127)
  1472.             runlen -= 256;
  1473.         if (runlen >= 0) {
  1474.             runlen++;
  1475.             FRead (rp, runlen);
  1476.             rp += runlen;
  1477.             linebytes -= runlen;
  1478.         }
  1479.         else {
  1480.             runlen = -runlen + 1;
  1481.             linebytes -= runlen;
  1482.             pixel = getc (fin);
  1483.             do
  1484.                 *(rp++) = pixel;
  1485.             while (--runlen);
  1486.         }
  1487.     }
  1488. }
  1489.  
  1490.  /*
  1491.   * Convert - convert (r,g,b) to hex greyscale.
  1492.   */
  1493.  
  1494. static short Convert(r,g,b)
  1495.     unsigned char   r,g,b;
  1496. {
  1497.     short   i,
  1498.             rd, gd, bd,
  1499.             min,
  1500.             dist,
  1501.             best;
  1502.  
  1503.  /* convert color according to 'Method' */
  1504.     switch (Method) {
  1505.         case AVERAGE:           /* average r,g,b to obtain grey level */
  1506.             return ((r + g + b) / 3);
  1507.         case LUMIN:             /* use NTSC luminescence as grey level */
  1508.             return ((r * 30 + g * 59 + b * 11) / 100);
  1509.         case DIST:          /* use grey with minimum distance in color */
  1510.             min = 15*15 * 3;
  1511.             for( i = 0; i < numcolors; i++ ) {
  1512.                 rd = r -i;
  1513.                 gd = g - i;
  1514.                 bd = b - i;
  1515.                 dist = rd * rd + gd * gd + bd * bd;
  1516.                 if( dist < min ) {
  1517.                     min = dist; best = i;
  1518.                 }
  1519.             }
  1520.             return( best );
  1521.         case REDONLY:
  1522.             return(r);
  1523.         case GREENONLY:
  1524.             return(g);
  1525.         case BLUEONLY:
  1526.             return(b);
  1527.  
  1528.     }
  1529. }                               /* Convert */
  1530.  
  1531. static void InitColorMappings()
  1532. {
  1533.     int     i;
  1534.  
  1535.  /* put colors in 4-bit range and Convert */
  1536.     for (i = 0; i < 32; i++) {
  1537.         cmap[i][RED] >>= 4;
  1538.         cmap[i][GRN] >>= 4;
  1539.         cmap[i][BLU] >>= 4;
  1540.         Color[i] = Convert (cmap[i][RED], cmap[i][GRN], cmap[i][BLU]);
  1541.     }
  1542. }
  1543.  
  1544.  
  1545. /*
  1546.  * leftmost pixel of byte is in most significant bit of byte
  1547.  */
  1548. static char GetIlbmVal( rastlist, h, bpp )
  1549.     char *rastlist[6];
  1550.     int h, bpp;
  1551. {
  1552.     int i;
  1553.     char value = 0;
  1554.     short mask, bytep;
  1555.  
  1556.     mask = 0x80 >> ( h & 7);
  1557.     bytep = h >> 3;
  1558.  
  1559.     for( i = bpp-1; i >= 0; i-- ) {
  1560.         value <<= 1;
  1561.         value |= (*(rastlist[i]+bytep) & mask) ? 1: 0;
  1562.     }
  1563.     return( value );
  1564. }
  1565.  
  1566.  /*
  1567.   * HamOut - output ham image in hex.
  1568.   */
  1569. static void HamOut(rastlist, pixwidth, v)
  1570.     char *rastlist[6];
  1571.     int pixwidth, v;
  1572. {
  1573.     unsigned char   lastred = 0,
  1574.                     lastgreen = 0,
  1575.                     lastblue = 0;
  1576.     int     h;
  1577.     char pixval;
  1578.     for( h = 0; h <pixwidth; h++ ) {
  1579.         short shade;
  1580.  
  1581.         shade = GetIlbmVal(rastlist, h, 6);
  1582.         pixval = shade & 0x0F;
  1583.         switch (shade & 0x30) {
  1584.         case 0x00:
  1585.             lastred = cmap[pixval][RED];
  1586.             lastgreen = cmap[pixval][GRN];
  1587.             lastblue = cmap[pixval][BLU];
  1588.             shade = Color[pixval];
  1589.             break;
  1590.         case 0x10:
  1591.             lastblue = pixval;
  1592.             shade = Convert(lastred,lastgreen,lastblue);
  1593.             break;
  1594.         case 0x20:
  1595.             lastred = pixval;
  1596.             shade = Convert(lastred,lastgreen,lastblue);
  1597.             break;
  1598.         case 0x30:
  1599.             lastgreen = pixval;
  1600.             shade = Convert(lastred,lastgreen,lastblue);
  1601.         }
  1602.         SetImgPix(h, v, shade);
  1603.     }
  1604. }
  1605.  
  1606.  /*
  1607.   * RastOut - handle normal bit mapped images
  1608.   */
  1609. static void RastOut(rastlist, pixwidth, v, depth)
  1610.     char *rastlist[6];
  1611.     int pixwidth, v, depth;
  1612. {
  1613.     int h, bit;
  1614.     for( h = 0; h < pixwidth; h++ ) {
  1615.         short shade;
  1616.         shade = Color[GetIlbmVal( rastlist, h, depth)];
  1617.         SetImgPix( h, v, shade);
  1618.     }
  1619. }
  1620.  
  1621.  /*
  1622.   * ReadChunk - read in an IFF Chunk.
  1623.   */
  1624.  
  1625. static void ReadChunk()
  1626. {
  1627.     FRead (&Chunk, sizeof (Chunk));
  1628.  
  1629. }                               /* ReadChunk */
  1630.  
  1631.  /*
  1632.   * ReadBMHD - read the BMHD structure.
  1633.   */
  1634.  
  1635. static void ReadBMHD(bmhd)
  1636. struct BMHD *bmhd;
  1637. {
  1638.     FRead (bmhd, Chunk.Size);
  1639. }                               /* ReadBMHD */
  1640.  
  1641.  
  1642.  /*
  1643.   * FRead - read 'len' bytes to 'pointer' while checking for an error.
  1644.   */
  1645.  
  1646. static void FRead(pointer,len)
  1647. char    *pointer;
  1648. int     len;
  1649. {
  1650.     if (fread (pointer, len, 1, fin) == 0)  {
  1651.         char outbuff[90];
  1652.         sprintf(outbuff,"Fread Error in reading input file at %d ", ftell(fin));
  1653.         OutErr(outbuff);
  1654.     }
  1655. }                               /* FRead */
  1656. \Rogue\Monster\
  1657. else
  1658.   echo "will not over write ./readilbm.c"
  1659. fi
  1660. if `test ! -s ./readilbm.h`
  1661. then
  1662. echo "writing ./readilbm.h"
  1663. cat > ./readilbm.h << '\Rogue\Monster\'
  1664. #ifndef READILBM_H_FILE
  1665.  
  1666. #define READILBM_H_FILE
  1667.  
  1668. #ifndef MYTYPES_H_FILE
  1669. #include "mytypes.h"
  1670. #endif MYTYPES_H_FILE
  1671.  
  1672. #define DefRepV 1
  1673. #define DefRepH 1
  1674.  
  1675. /*
  1676.  * how many times the image should be replicated on screen
  1677.  */
  1678. extern short MapRepV, MapRepH;
  1679.  
  1680. /*
  1681.  * Size of image read in
  1682.  */
  1683. extern int MapImageV, MapImageH;
  1684. /*
  1685.  * ReadPixel returns an intensity between 0-255
  1686.  */
  1687. extern short GetImgPix(/* short vert, hori */);
  1688. extern void CloseImgPix();
  1689. bool OpenImgPix( /* int sizex, sizey; short maxshade */);
  1690. void SetImgPix( /* int x, y; short val */ );
  1691. short GetImgPix( /* int x, y */);
  1692. extern void PrepImgPix(/* void */);
  1693. #define DefXYFlip false
  1694. extern void FlipImgPix( /* bool flip */);
  1695. extern void SetGreyModel( /* int */);
  1696.  
  1697. #endif READILBM_H_FILE
  1698.  
  1699. \Rogue\Monster\
  1700. else
  1701.   echo "will not over write ./readilbm.h"
  1702. fi
  1703. if `test ! -s ./revolve.c`
  1704. then
  1705. echo "writing ./revolve.c"
  1706. cat > ./revolve.c << '\Rogue\Monster\'
  1707. #include <math.h>
  1708. #include "fasttrig.h"
  1709. #include "bezpt.h"
  1710. #include "revolve.h"
  1711. #include "mytypes.h"
  1712.  
  1713.  
  1714. RevAxisType RevAxis;
  1715.  
  1716.  
  1717. short RevMesh = DefRevMeshVal;
  1718. short RevImageR, /* revolution index */
  1719.       RevImageB; /* bezier index */
  1720.  
  1721. static int RotRange = DefRotRange;
  1722. static int RotStart = DefRotStart;
  1723. static int SecAngle = DefTilt;
  1724. static float SurfDist = DefSurfDist;
  1725. static float ViewDist = DefViewDist;
  1726. static bool Perspective = DefPersp;
  1727.  
  1728. void SetPerspective(  value)
  1729.     int value;
  1730. {
  1731.     Perspective = value;
  1732. }
  1733.  
  1734.  
  1735.  
  1736. void SetRevAxis( value)
  1737.     int value;
  1738. {
  1739.     RevAxis = (value)? RevY : RevX;
  1740. }
  1741.  
  1742.  
  1743. void SetRotStart( value )
  1744.     int value;
  1745. {
  1746.     RotStart = value;
  1747. }
  1748.  
  1749. void SetRotRange(  value )
  1750.     int value;
  1751. {
  1752.     RotRange = value;
  1753. }
  1754.  
  1755. void SetSecAng( value )
  1756.     int value;
  1757. {
  1758.     SecAngle = value;
  1759. }
  1760.  
  1761. void SetRevMesh( value )
  1762.     int value;
  1763. {
  1764.     RevMesh = value;
  1765. }
  1766.  
  1767.  
  1768. void SetSurfDist( value )
  1769.     int value;
  1770. {
  1771.     SurfDist = (float )value;
  1772. }
  1773.  
  1774.  
  1775. void SetViewDist( value )
  1776.     int value;
  1777. {
  1778.     ViewDist = (float )value;
  1779. }
  1780.  
  1781.  
  1782.  
  1783. static
  1784. float secsin, seccos; /* trig values of secondary angle */
  1785.  
  1786. static
  1787. int sizeptlist = 0;
  1788.  
  1789. static
  1790. PtGen *ptlist1 = 0,
  1791.       *ptlist2 = 0;
  1792.  
  1793. static
  1794. int NumEnts; /* number of angle slices */
  1795.  
  1796.  
  1797. static
  1798. bool PrepRev()
  1799. {
  1800.     NumEnts = RevMesh+1;
  1801.  
  1802.     /*
  1803.      * allocate space 3d descriptions of a point revolved x degrees
  1804.      */
  1805.     if( NumEnts > sizeptlist ) {
  1806.         if( ptlist1 ) free(ptlist1);
  1807.         if( ptlist2 ) free(ptlist2);
  1808.  
  1809.         ptlist1 =(PtGen *) malloc( NumEnts * sizeof(PtGen)  );
  1810.         ptlist2 =(PtGen *) malloc( NumEnts * sizeof(PtGen)  );
  1811.         if( !ptlist1 || !ptlist2 ) {
  1812.             OutErr("PrepRev:not enough memory");
  1813.             return(true);
  1814.         }
  1815.     }
  1816.  
  1817.  
  1818.     if( InitFastTrig( RotStart, RotRange, NumEnts)) return(true);
  1819.     secsin = sin((float)SecAngle*PI/180);
  1820.     seccos = cos((float)SecAngle*PI/180);
  1821.     return (false);
  1822. }
  1823.  
  1824.  
  1825. static
  1826. void CalcRing(ptlist, xpos, ypos)
  1827. register PtGen *ptlist;
  1828. float xpos, ypos;
  1829. {
  1830.     int angle;
  1831.  
  1832.     for( angle = 0; angle < NumEnts; angle++, ptlist++) {
  1833.         float temp;
  1834.         /*
  1835.          * calculate 3d coordinate of point revolved
  1836.          */
  1837.         if( RevAxis == RevX) {
  1838.             ptlist->d3.y = ypos * fcos(angle);
  1839.             temp = ypos * fsin(angle);
  1840.             ptlist->d3.x = xpos* seccos - temp *secsin;
  1841.             ptlist->d3.z = xpos * secsin + temp * seccos;
  1842.         }
  1843.         else {
  1844.             ptlist->d3.x = xpos * fcos(angle);
  1845.             temp = xpos * fsin( angle);
  1846.             ptlist->d3.y = ypos * seccos + temp * secsin;
  1847.             ptlist->d3.z = secsin * ypos - temp * seccos;
  1848.         }
  1849.         ptlist->d3.z -= SurfDist;
  1850.  
  1851.         if( Perspective ) {
  1852.             float PerspScale;
  1853.  
  1854.             PerspScale = fabs(ViewDist / ptlist->d3.z);
  1855.             ptlist->d3.x *= PerspScale;
  1856.             ptlist->d3.y *= PerspScale;
  1857.         }
  1858.         /*
  1859.          * calculate the 2d screen coordinate equvalent
  1860.          */
  1861.       /*
  1862.         ptlist->d2.x = (short) ptlist->d3.x;
  1863.         ptlist->d2.y = (short) ptlist->d3.y;
  1864.        */
  1865.         ptlist->d2.x = (short) (ptlist->d3.x + 0.5);
  1866.         ptlist->d2.y = (short) (ptlist->d3.y + 0.5);
  1867.     }
  1868. }
  1869.  
  1870.  
  1871.  
  1872.  
  1873.  
  1874.  
  1875. /*
  1876.  * return true on failure
  1877.  */
  1878. bool Revolve(acceptfunc)
  1879. void (*acceptfunc)();
  1880. {
  1881.     int segno;
  1882.     float tparm, deltat;
  1883.     int angle;
  1884.     int subseg;
  1885.  
  1886.     if( PrepRev() ) {
  1887.         return(true);
  1888.     }
  1889.  
  1890.     deltat = 1.0/BezMesh;
  1891.     RevImageB = 0;
  1892.     ResetActSeg();
  1893.     do {
  1894.         float xpos, ypos;
  1895.  
  1896.  
  1897.         InitCalcBez();
  1898.         xpos = StartPtX(GetCurSeg());
  1899.         ypos = StartPtY(GetCurSeg());
  1900.         CalcRing(ptlist1, xpos, ypos );
  1901.         for( subseg = 1; subseg <= BezMesh; subseg++ ) {
  1902.             register PtGen *ptlista, *ptlistb;
  1903.             register int numpoly;
  1904.  
  1905.             tparm = subseg * deltat;
  1906.             if( subseg & 1 ) {
  1907.                 ptlista = ptlist2; ptlistb = ptlist1;
  1908.             }
  1909.             else {
  1910.                 ptlista = ptlist1; ptlistb = ptlist2;
  1911.             }
  1912.  
  1913.             CalcBezPt(tparm, &xpos, &ypos );
  1914.             CalcRing( ptlista, xpos, ypos );
  1915.             RevImageR = 0;
  1916.             for( numpoly = NumEnts -1; numpoly--; ) {
  1917.      /*         (* acceptfunc)(ptlista, ptlista+1, ptlistb+1, ptlistb); */
  1918.                 (* acceptfunc)(ptlistb, ptlista, ptlista+1, ptlistb+1);
  1919.                 ptlista++;
  1920.                 ptlistb++;
  1921.                 RevImageR++;
  1922.             }
  1923.             RevImageB++;
  1924.         }
  1925.         NextSeg();
  1926.  
  1927.     } while( ActSeg );
  1928.     return( false );
  1929. }
  1930. \Rogue\Monster\
  1931. else
  1932.   echo "will not over write ./revolve.c"
  1933. fi
  1934. if `test ! -s ./revolve.h`
  1935. then
  1936. echo "writing ./revolve.h"
  1937. cat > ./revolve.h << '\Rogue\Monster\'
  1938. #ifndef REVOLVE_H_FILE
  1939.  
  1940. #define REVOLVE_H_FILE
  1941. #include "mytypes.h"
  1942.  
  1943. typedef enum { RevX, RevY } RevAxisType;
  1944. extern RevAxisType RevAxis;
  1945.  
  1946. #define DefRevMeshVal 30
  1947. #define DefSurfDist 3000
  1948. #define DefTilt 15
  1949. #define DefRotRange 360
  1950. #define DefRotStart 0
  1951. #define DefPersp false
  1952. #define DefViewDist 3000
  1953.  
  1954. typedef struct {
  1955.     short x, y;
  1956. } ScrnPair;
  1957.  
  1958.  
  1959.  
  1960.  
  1961. typedef struct {
  1962.         float x, y, z;
  1963. } Pt3;
  1964.  
  1965. typedef struct {
  1966.         Pt3 d3;
  1967.         ScrnPair d2;
  1968. } PtGen;
  1969.  
  1970. extern short RevMesh;
  1971. extern short RevImageR,
  1972.              RevImageB;
  1973.  
  1974. extern void SetRotStart();
  1975. extern void SetRotRange(/* Panel_item, int, struct input_event */);
  1976. extern void SetSecAng(/* Panel_item, int, struct input_event */);
  1977. extern void SetPolyMode( /* Panel_item, int, struct input_event */);
  1978. extern void SetFitBez( /* Panel_item, int, struct input_event */);
  1979. extern bool Revolve( /* Panel_item, int, struct input_event */);
  1980. extern void SetRevAxis( /* Panel_item, int, struct input_event */);
  1981. extern void SetRevMesh( /* Panel_item, int, struct input_event */);
  1982. extern void SetSurfDist(/* Panel_item, int, struct input_event */);
  1983. extern void SetViewDist();
  1984. extern void SetPerspective();
  1985. #endif !REVOLVE_H_FILE
  1986. \Rogue\Monster\
  1987. else
  1988.   echo "will not over write ./revolve.h"
  1989. fi
  1990. if `test ! -s ./scrndef.c`
  1991. then
  1992. echo "writing ./scrndef.c"
  1993. cat > ./scrndef.c << '\Rogue\Monster\'
  1994. /* this file contains definition for the screen */
  1995.  
  1996. #include <exec/types.h>
  1997. #include <intuition/intuition.h>
  1998. #include <graphics/gfxmacros.h>
  1999. #ifdef MANX
  2000. #include <functions.h>
  2001. #endif
  2002.  
  2003. #include "scrndef.h"
  2004.  
  2005. struct TextAttr myfont1 = {
  2006.     (UBYTE *)"topaz.font", 8, 0, 0
  2007. };
  2008.  
  2009.  
  2010.  
  2011. struct NewScreen SurfScrnDef = {
  2012.     0,0,   /* left and top edge */
  2013.     SurfInitW, SurfInitH+ButHeight,  /* width and height */
  2014.     SurfInitD,   /* num bitplanes bit planes */
  2015.     0,1, /* detail, block pen */
  2016.     SurfInitType, /* lores non interlaced */
  2017.     CUSTOMSCREEN,
  2018.     &myfont1,
  2019.     NULL /*(UBYTE *) "Screen" */,
  2020.     NULL,
  2021.     NULL
  2022. };
  2023.  
  2024.  
  2025. struct NewWindow SurfWinDef = {
  2026.     0, ButHeight, /* left, top */
  2027.     SurfInitW, SurfInitH, /* width, height */
  2028.     -1, -1, /* default detail and block pen */
  2029.     MOUSEBUTTONS | MOUSEMOVE| INTUITICKS /* | CLOSEWINDOW */,
  2030.     RMBTRAP | SIMPLE_REFRESH | GIMMEZEROZERO | BORDERLESS
  2031.      | BACKDROP,
  2032.     NULL, NULL, /* gadget, checkmark */
  2033.     NULL /* (UBYTE *) "BezSurf - By Eric Davies" */,
  2034.     NULL, /* pointer to screen */
  2035.     NULL, /* pointer to super bitmap */
  2036.     10, 10, 640, 200, /* min and max dimensions */
  2037.     CUSTOMSCREEN
  2038. };
  2039.  
  2040. struct NewWindow GadWinDef = {
  2041.     0, 0, /* left, top */
  2042.     SurfInitW, ButHeight, /* width, height */
  2043.     -1, 0, /* default detail and block pen */
  2044.     GADGETUP,
  2045.     SIMPLE_REFRESH | BORDERLESS | BACKDROP,
  2046.     NULL, NULL, /* gadget, checkmark */
  2047.     NULL /*(UBYTE *) "Gadwin" */,
  2048.     NULL, /* pointer to screen */
  2049.     NULL, /* pointer to super bitmap */
  2050.     10, 10, 10, 10, /* min and max dimensions */
  2051.     CUSTOMSCREEN
  2052. };
  2053.  
  2054.  
  2055.  
  2056. struct NewWindow CntrlWinDef = {
  2057.     0, 0, /* left, top */
  2058.     640, 180, /* width, height */
  2059.     -1, -1, /* default detail and block pen */
  2060.     CLOSEWINDOW| GADGETUP| MENUPICK,
  2061.     SIMPLE_REFRESH | WINDOWCLOSE | WINDOWDEPTH
  2062.     | WINDOWDRAG | WINDOWSIZING,
  2063.     NULL, NULL, /* gadget(set by program), checkmark */
  2064.     (UBYTE *)  "BezSurf - Control Panel - By Eric Davies",
  2065.     NULL, /* pointer to screen */
  2066.     NULL, /* pointer to super bitmap */
  2067.     10, 10, 640, 200, /* min and max dimensions */
  2068.     WBENCHSCREEN
  2069. };
  2070. \Rogue\Monster\
  2071. else
  2072.   echo "will not over write ./scrndef.c"
  2073. fi
  2074. if `test ! -s ./scrndef.h`
  2075. then
  2076. echo "writing ./scrndef.h"
  2077. cat > ./scrndef.h << '\Rogue\Monster\'
  2078. #ifndef SCRNDEF_H_FILE
  2079. #define SCRNDEF_H_FILE
  2080.  
  2081. #define ButHeight 10   /* height of GadWin */
  2082. #define SurfInitW 320  /* initial width */
  2083. #define SurfInitH 200  /* initial height */
  2084. #define SurfInitD 4    /* 16 color */
  2085. #define SurfInitType 0 /* Lores */
  2086.  
  2087. extern struct NewWindow SurfWinDef;
  2088. extern struct NewWindow CntrlWinDef;
  2089. extern struct NewScreen SurfScrnDef;
  2090. extern struct NewWindow GadWinDef;
  2091.  
  2092. #endif !SCRNDEF_H_FILE
  2093.  
  2094. \Rogue\Monster\
  2095. else
  2096.   echo "will not over write ./scrndef.h"
  2097. fi
  2098. if `test ! -s ./scrnio.c`
  2099. then
  2100. echo "writing ./scrnio.c"
  2101. cat > ./scrnio.c << '\Rogue\Monster\'
  2102. /* main program */
  2103.  
  2104. #include "scrnio.ih"
  2105. /*#include <functions.h>*/
  2106.  
  2107. #include "scrndef.h"
  2108. #include "scrnio.h"
  2109. #include "gadgetdef.h"
  2110. #include "menudef.h"
  2111.  
  2112. struct Screen *SurfScrn = NULL;
  2113. struct Window *SurfWin = NULL;
  2114. struct Window *CntrlWin = NULL;
  2115. struct Window *GadWin = NULL;
  2116. /*
  2117.  * bit masks for waiting for signals
  2118.  */
  2119. short CntrlSigBit, SurfSigBit, GadSigBit;
  2120. long SignalMask = 0;
  2121.  
  2122. struct RastPort *rp;
  2123. struct ViewPort *vp;
  2124.  
  2125. struct Library *GfxBase = 0,
  2126.                *IntuitionBase = 0;
  2127.  
  2128. int XOR = COMPLEMENT, /* so my other modules don't need to */
  2129.     WRITE = JAM1;     /* include so many amiga includes */
  2130.  
  2131. int WinHOrig, WinVOrig;
  2132. int WinFgCol;
  2133. int ColorMax;
  2134. int NumColors;
  2135.  
  2136. /*
  2137.  * data structures needed to use amiga polygons routines
  2138.  */
  2139. static WORD PolyArea[5*5];
  2140. static struct AreaInfo PolyInfo;
  2141. static PLANEPTR PolyWorkSpace;
  2142. static struct TmpRas PolyTmpRas;
  2143.  
  2144.  
  2145.  
  2146. static void ResetWinDat() {
  2147.  
  2148.     WinHOrig = SurfWinDef.Width >>1;
  2149.     WinVOrig = SurfWinDef.Height >>1;
  2150.  
  2151.  
  2152.     rp = SurfWin->RPort;
  2153.     SetDrMd( rp,  JAM1 );
  2154. }
  2155.  
  2156.  
  2157.  
  2158. /*
  2159.  * open surface window/screen
  2160.  */
  2161. OpenSurf() {
  2162.     NumColors = 1 << SurfScrnDef.Depth;
  2163.     ColorMax = ( NumColors -1) * 8 + 1;
  2164.     WinFgCol = (NumColors - 1) & 0x1f;
  2165.  
  2166.     SurfScrnDef.BlockPen = ( WinFgCol *3) /4;
  2167.     SurfScrnDef.DetailPen = WinFgCol>>2;
  2168.  
  2169.     SurfScrn = OpenScreen( &SurfScrnDef );
  2170.     MenuSetColMap();
  2171.     SurfWinDef.Screen = GadWinDef.Screen = SurfScrn;
  2172.     SurfWinDef.Width = GadWinDef.Width = SurfScrnDef.Width;
  2173.     SurfWinDef.Height = SurfScrnDef.Height - ButHeight;
  2174.  
  2175.     SurfWin = OpenWindow( &SurfWinDef );
  2176.     GadWin = OpenWindow( &GadWinDef );
  2177.     SurfSigBit = SurfWin->UserPort->mp_SigBit;
  2178.     GadSigBit = GadWin->UserPort->mp_SigBit;
  2179.     SignalMask = (1<<CntrlSigBit) | (1<<SurfSigBit)| (1<<GadSigBit);
  2180.  
  2181.     ResetWinDat();
  2182.     ShowTitle( SurfScrn, 0L ); /* hide screen title behind backdrop */
  2183.  
  2184.     InitArea( &PolyInfo, PolyArea, 5);
  2185.     rp->AreaInfo = &PolyInfo;
  2186.  
  2187.     PolyWorkSpace = AllocRaster( SurfWinDef.Width, SurfWinDef.Height);
  2188.  
  2189.     if( !PolyWorkSpace ) {
  2190.         CloseDisplay();
  2191.         perror("no space for temporary rastern");
  2192.         exit(0);
  2193.     }
  2194.     else {
  2195.         InitTmpRas( &PolyTmpRas, PolyWorkSpace,
  2196.                     RASSIZE( SurfWinDef.Width, SurfWinDef.Height ));
  2197.         rp->TmpRas = &PolyTmpRas;
  2198.     }
  2199. }
  2200.  
  2201.  
  2202. void InitWindow()
  2203. {
  2204.     GfxBase = OpenLibrary("graphics.library",0);
  2205.     if( GfxBase == 0 ) {
  2206.         OutErr("graphics library won't open");
  2207.         exit(10);
  2208.     }
  2209.  
  2210.     IntuitionBase = OpenLibrary("intuition.library",0);
  2211.     if( IntuitionBase == 0 ) {
  2212.         OutErr("intuition library won't open");
  2213.         exit(10);
  2214.     }
  2215.  
  2216.     InitGadgets();
  2217.     CntrlWin = OpenWindow( &CntrlWinDef );
  2218.     CntrlSigBit = CntrlWin->UserPort->mp_SigBit;
  2219.  
  2220.     MenuSetScrn();
  2221.  
  2222.     if( !SurfScrn || !SurfWin || !CntrlWin ) {
  2223.         OutErr("couldn't open at least one window or screen");
  2224.         CloseDisplay();
  2225.         exit( 0 );
  2226.     }
  2227.  
  2228.     SetMenuStrip(CntrlWin, menu );
  2229. }
  2230.  
  2231.  
  2232. /*
  2233.  * remove surface window/screen
  2234.  */
  2235. CloseSurf() {
  2236.  
  2237.     if( PolyWorkSpace)
  2238.         FreeRaster( PolyWorkSpace, SurfWinDef.Width, SurfWinDef.Height );
  2239.  
  2240.     if( SurfWin )
  2241.         CloseWindow( SurfWin );
  2242.  
  2243.     if( GadWin )
  2244.         CloseWindow( GadWin );
  2245.  
  2246.     if( SurfScrn )
  2247.         CloseScreen( SurfScrn );
  2248. }
  2249.  
  2250.  
  2251. void CloseDisplay()
  2252. {
  2253.  
  2254.     CloseSurf();
  2255.  
  2256.  
  2257.     if( CntrlWin ) {
  2258.         ClearMenuStrip( CntrlWin );
  2259.         CloseWindow( CntrlWin );
  2260.     }
  2261.  
  2262.     EndGadgets();
  2263.  
  2264.     if ( IntuitionBase )
  2265.         CloseLibrary(IntuitionBase);
  2266.  
  2267.     if ( GfxBase )
  2268.         CloseLibrary(GfxBase);
  2269. }
  2270.  
  2271.  
  2272. \Rogue\Monster\
  2273. else
  2274.   echo "will not over write ./scrnio.c"
  2275. fi
  2276. if `test ! -s ./scrnio.h`
  2277. then
  2278. echo "writing ./scrnio.h"
  2279. cat > ./scrnio.h << '\Rogue\Monster\'
  2280. extern void InitWindow();
  2281. extern void CloseDisplay();
  2282. extern void SetMono();
  2283. extern void ClearWindow();
  2284. extern void DrawPoly();
  2285.  
  2286. extern int WinHOrig, WinVOrig;
  2287. extern int XOR, WRITE;
  2288. extern short DitherMask;
  2289.  
  2290. #define CntrX(XVAL) ((XVAL) - WinHOrig)
  2291. #define CntrY(YVAL) (WinVOrig - (YVAL)) /* fudge for the mouse */
  2292.  
  2293. #define UCntrX(XVAL) ((XVAL) + WinHOrig)
  2294. #define UCntrY(YVAL) (WinVOrig - (YVAL))
  2295.  
  2296. \Rogue\Monster\
  2297. else
  2298.   echo "will not over write ./scrnio.h"
  2299. fi
  2300. if `test ! -s ./scrnio.ih`
  2301. then
  2302. echo "writing ./scrnio.ih"
  2303. cat > ./scrnio.ih << '\Rogue\Monster\'
  2304. /* main program */
  2305.  
  2306. #include <exec/types.h>
  2307. #include <intuition/intuition.h>
  2308. #include <graphics/gfxmacros.h>
  2309.  
  2310.  
  2311. extern struct Screen *SurfScrn;
  2312. extern struct Window *SurfWin;
  2313. extern struct Window *CntrlWin;
  2314. extern struct Window *GadWin;
  2315. extern long BackColor;
  2316. /*
  2317.  * bit masks for waiting for signals
  2318.  */
  2319. extern short CntrlSigBit, SurfSigBit, GadSigBit;
  2320. extern long SignalMask;
  2321.  
  2322. extern struct RastPort *rp;
  2323. extern struct ViewPort *vp;
  2324.  
  2325.  
  2326.  
  2327. extern int WinFgCol;
  2328. extern int ColorMax;
  2329. extern int NumColors;
  2330.  
  2331. extern UWORD GrayPat[9][4];
  2332.  
  2333. #define DefBkPlane 0
  2334.  
  2335. \Rogue\Monster\
  2336. else
  2337.   echo "will not over write ./scrnio.ih"
  2338. fi
  2339. if `test ! -s ./scrnops.c`
  2340. then
  2341. echo "writing ./scrnops.c"
  2342. cat > ./scrnops.c << '\Rogue\Monster\'
  2343. #include "scrnio.ih"
  2344. #ifdef MANX
  2345. #include <functions.h>
  2346. #endif
  2347.  
  2348. #include "scrndef.h"
  2349. #include "scrnio.h"
  2350. #include "gadgetdef.h"
  2351. #include "menudef.h"
  2352.  
  2353. #include "bezpt.h"
  2354. #include "revolve.h"
  2355. #include "control.h"
  2356. #include "poly.h"
  2357.  
  2358.  
  2359. long BackColor = DefBkPlane;
  2360. short DitherMask = 7;
  2361.  
  2362. void SetMono( maxrval, maxgval, maxbval )
  2363.     short maxrval,
  2364.           maxgval,
  2365.           maxbval;
  2366. {
  2367.     long i;
  2368.     short range;
  2369.     long rval, gval, bval;
  2370.  
  2371.     range = (NumColors -1) & 0x1f;  /* max 32 colours */
  2372.     for( i = 0; i <= range; i++ ) {
  2373.         rval = (maxrval * i )/range;
  2374.         gval = (maxgval * i )/range;
  2375.         bval = (maxbval * i )/range;
  2376.  
  2377.         SetRGB4( &(SurfScrn->ViewPort),  i, rval, gval, bval );
  2378.     }
  2379. }
  2380.  
  2381.  
  2382. void SetRainbow()
  2383. {
  2384.     long i;
  2385.     short range;
  2386.     long rval, gval, bval;
  2387.  
  2388.     range = NumColors>> 1;
  2389.     /*
  2390.      * can't do a rainbow with only 2 colors
  2391.      */
  2392.     if( range < 2) {
  2393.         return;
  2394.     }
  2395.  
  2396.     for( i = 0; i < range; i++ ) {
  2397.         long diff;
  2398.  
  2399.         diff = (0xf * i )/(range-1);
  2400.         rval = 0xf - diff;
  2401.         bval = diff;
  2402.         gval = 0xf;
  2403.         SetRGB4( &(SurfScrn->ViewPort), i, rval, gval, bval);
  2404.     }
  2405.     for( i = 0; i < range; i++ ) {
  2406.         long diff;
  2407.  
  2408.         diff = (0xf * i )/(range-1);
  2409.         rval = diff;
  2410.         bval = 0xf;
  2411.         gval = 0xf - diff;
  2412.         SetRGB4( &(SurfScrn->ViewPort), i+range, rval, gval, bval);
  2413.     }
  2414.     SetRGB4( &(SurfScrn->ViewPort), 0L, 0L, 0L, 0L);
  2415. }
  2416.  
  2417. /*
  2418.  * set colours for hourglass pointer
  2419.  */
  2420. SetHourGlassCol()
  2421. {
  2422.     SetRGB4( &(SurfScrn->ViewPort),17L, 6L, 2L, 3L );
  2423.     SetRGB4( &(SurfScrn->ViewPort),18L, 0L, 0L, 0L );
  2424.     SetRGB4( &(SurfScrn->ViewPort),19L, 9L, 7L, 6L );
  2425. }
  2426.  
  2427.  
  2428.  
  2429. void ClrWindow(drawaxis)
  2430. bool drawaxis;
  2431. {
  2432.     long BkColAdj; /* background color adjusted for number of bit planes */
  2433.  
  2434.     BkColAdj = (BackColor * NumColors) / 32;
  2435.     SetRast(rp, BackColor);  /* clear the window to colour 0 */
  2436.     SetAPen(rp, WinFgCol );
  2437.     /*
  2438.      * Draw axis on screen
  2439.      */
  2440.     if( drawaxis) {
  2441.         Move( rp, 0, WinVOrig);    /* x axis */
  2442.         Draw( rp, (long)SurfWinDef.Width, (long)WinVOrig );
  2443.  
  2444.         Move( rp, WinHOrig, 0);     /* y axis */
  2445.         Draw( rp, (long)WinHOrig, (long)SurfWinDef.Height );
  2446.     }
  2447. }
  2448.  
  2449.  
  2450.  
  2451.  
  2452.  
  2453. void DrawLine( x1, y1, x2, y2, mode )
  2454. int x1, y1, x2, y2;
  2455. int mode;
  2456. {
  2457.     SetDrMd( rp, mode );
  2458.     Move( rp, (long)UCntrX(x1), (long)UCntrY(y1));
  2459.     Draw(rp, (long)UCntrX(x2), (long)UCntrY(y2) );
  2460. }
  2461.  
  2462.  
  2463.  
  2464. void PaintPoint(x,y,forecolor)
  2465.     short x, y;
  2466.     float forecolor;
  2467. {
  2468.     long shade;
  2469.     shade = forecolor * (NumColors-1);
  2470.  
  2471.     if( shade >= NumColors) {
  2472.         shade = NumColors-1;
  2473.     }
  2474.     else if ( shade < 0 ) {
  2475.         shade = 0;
  2476.     }
  2477.  
  2478.     SetAPen( rp, shade );
  2479.     WritePixel( rp, (long)UCntrX(x), (long)UCntrY(y));
  2480. }
  2481.  
  2482.  
  2483.  
  2484. void DrawPnt( x, y, op )
  2485. int x, y, op;
  2486. {
  2487.     x = UCntrX(x);
  2488.     y = UCntrY(y);
  2489.     SetDrMd(rp, op );
  2490.     RectFill( rp, (long)x, (long)y, (long)x, (long)y);
  2491. }
  2492.  
  2493.  
  2494. void DrawSqr(x, y, op )
  2495. int x, y, op;
  2496. {
  2497.     x = UCntrX(x);
  2498.     y = UCntrY(y);
  2499.     SetDrMd(rp, op );
  2500.     RectFill( rp, x - 2L, y -2L, x+ 2L, y+2L );
  2501. }
  2502.  
  2503.  
  2504. void DrawRhomShade( poly)
  2505. Rhomboid *poly;
  2506. {
  2507.     int i;
  2508.     int shade;
  2509.     long backcolor, forecolor;
  2510.  
  2511.  
  2512.     shade = (int)((poly->intensity) * ColorMax);
  2513.     if( shade > ColorMax) {
  2514.         shade = ColorMax;
  2515.     }
  2516.  
  2517.     backcolor = shade >> 3;
  2518.     forecolor = backcolor +1;
  2519.     if( forecolor >= NumColors ) {
  2520.         forecolor = backcolor;
  2521.     }
  2522.  
  2523.     SetDrMd( rp, JAM2);
  2524.     SetAPen( rp, forecolor );
  2525.     SetBPen( rp, backcolor );
  2526.     SetAfPt( rp, GrayPat[ shade & DitherMask ], 2);
  2527.  
  2528.     AreaMove( rp, UCntrX(poly->pt[0].x), UCntrY(poly->pt[0].y));
  2529.  
  2530.     for( i = 1; i < 4; i++ ) {
  2531.         AreaDraw( rp, UCntrX(poly->pt[i].x), UCntrY(poly->pt[i].y) );
  2532.     }
  2533.     AreaEnd(rp);
  2534.  
  2535.     SetAfPt( rp, GrayPat[8], 2);  /* reset back to solid */
  2536.  
  2537. }
  2538.  
  2539. void DrawRhomFrame( inlist )
  2540. ScrnPair inlist[];
  2541. {
  2542.     int i;
  2543.  
  2544.     SetDrMd( rp, JAM1);
  2545.     SetAPen( rp, 0L );
  2546.     SetOPen( rp, WinFgCol );
  2547.  
  2548.     AreaMove( rp, UCntrX(inlist[0].x), UCntrY(inlist[0].y));
  2549.  
  2550.     for( i = 1; i < 4; i++ ) {
  2551.         AreaDraw( rp, UCntrX(inlist[i].x), UCntrY(inlist[i].y) );
  2552.     }
  2553.     AreaEnd(rp);
  2554.     BNDRYOFF( rp ); /* turn off outlining */
  2555. }
  2556.  
  2557.  
  2558.  
  2559.  
  2560. SwitchBox()
  2561. {
  2562.     struct IntuiMessage mycopy,
  2563.                         *orig;
  2564.  
  2565.     RefreshGadgets(SurfWinDef.FirstGadget, SurfWin, NULL );
  2566.  
  2567.     while(1) {
  2568.         long wakeupmask;
  2569.  
  2570.         wakeupmask = Wait( SignalMask );
  2571.         /*
  2572.          * for now, we ignore the wakeupmask,
  2573.          * just read messages from each. if I notice a performance problem,
  2574.          * I'll fix it then
  2575.          */
  2576.  
  2577.         /*
  2578.          * handle messages for the control window
  2579.          */
  2580.         while( orig =(struct IntuiMessage *) GetMsg( CntrlWin->UserPort ) ) {
  2581.  
  2582.             mycopy = *orig;
  2583.             ReplyMsg( orig );
  2584.  
  2585.             switch( mycopy.Class ) {
  2586.                 case MENUPICK:
  2587.                     MenuHandler( mycopy.Code );
  2588.                     break;
  2589.  
  2590.                 case GADGETUP:
  2591.                     GadgetHandler( (struct Gadget*)mycopy.IAddress );
  2592.                     break;
  2593.  
  2594.                 case CLOSEWINDOW:
  2595.                     return;
  2596.  
  2597.                 default:
  2598.                     break;
  2599.             }
  2600.         }
  2601.         /*
  2602.          * handle the button window
  2603.          */
  2604.         while( orig =(struct IntuiMessage *) GetMsg( GadWin->UserPort ) ) {
  2605.  
  2606.             mycopy = *orig;
  2607.             ReplyMsg( orig );
  2608.  
  2609.             switch( mycopy.Class ) {
  2610.                 case GADGETUP:
  2611.                     GadgetHandler( (struct Gadget*)mycopy.IAddress );
  2612.                     RefreshGadgets(SurfWinDef.FirstGadget, SurfWin, NULL );
  2613.                     break;
  2614.  
  2615.                 default:
  2616.                     break;
  2617.             }
  2618.         }
  2619.  
  2620.         /*
  2621.          * handle messages for the other window
  2622.          */
  2623.         while( orig =(struct IntuiMessage *) GetMsg( SurfWin->UserPort ) ) {
  2624.  
  2625.             mycopy = *orig;
  2626.             ReplyMsg( orig );
  2627.  
  2628.             switch( mycopy.Class ) {
  2629.                 case MOUSEBUTTONS:
  2630.                     HandleMButtons(&mycopy);
  2631.                     break;
  2632.  
  2633.                 case INTUITICKS:
  2634.                     HandleTicks(&mycopy);
  2635.                     break;
  2636.  
  2637.                 case MOUSEMOVE:
  2638.                     break;
  2639.  
  2640.                 default:
  2641.                     break;
  2642.             }
  2643.         }
  2644.     }
  2645. }
  2646.  
  2647. /*
  2648.  * display error messages inside a requestor
  2649.  */
  2650. OutErr(errstr)
  2651.     char *errstr;
  2652. {
  2653.     static struct IntuiText errtext =
  2654.         { -1, -1, JAM1, 10, 10, NULL, NULL, NULL };
  2655.     static struct IntuiText negtext =
  2656.         { -1, -1, JAM1, 80, 20, NULL,(UBYTE *)"Onwards", NULL };
  2657.  
  2658.     errtext.IText = (UBYTE *)errstr;
  2659.  
  2660.     WBenchToFront();
  2661.     AutoRequest(CntrlWin, &errtext, NULL, &negtext, NULL, NULL,
  2662.         8*strlen(errstr)+ 40, 60 );
  2663.     WindowToFront( CntrlWin );
  2664.  
  2665. }
  2666.  
  2667. \Rogue\Monster\
  2668. else
  2669.   echo "will not over write ./scrnops.c"
  2670. fi
  2671. if `test ! -s ./surf.lnk`
  2672. then
  2673. echo "writing ./surf.lnk"
  2674. cat > ./surf.lnk << '\Rogue\Monster\'
  2675. ROOT     lib:c.o
  2676.     scrnio.o
  2677.     scrnops.o
  2678.     scrndef.o
  2679.     main.o
  2680.     gadgetdef.o
  2681.     menudef.o
  2682.     graypat.o
  2683.     mouse.o
  2684.     gadgetuse.o
  2685.     bezpt.o
  2686.     revolve.o
  2687.     control.o
  2688.     poly.o
  2689.     fasttrig.o
  2690.     readilbm.o
  2691.     writeilbm.o
  2692.     packer.o
  2693.     mapstuff.o
  2694.     mapcalc.o
  2695.     getfilenames.o
  2696.     mapimgpix.o
  2697.  
  2698.  
  2699. LIBRARY    LIB:lcmffp.lib
  2700.     Lib:lc.lib
  2701.     LIB:amiga.lib
  2702.  
  2703. TO Surf
  2704.  
  2705. verbose
  2706. nodebug
  2707. \Rogue\Monster\
  2708. else
  2709.   echo "will not over write ./surf.lnk"
  2710. fi
  2711. if `test ! -s ./writeilbm.c`
  2712. then
  2713. echo "writing ./writeilbm.c"
  2714. cat > ./writeilbm.c << '\Rogue\Monster\'
  2715. #include <stdio.h>
  2716. #include <exec/types.h>
  2717. #include <intuition/intuition.h>
  2718. #include <graphics/gfxmacros.h>
  2719. #ifdef MANX
  2720. #include <functions.h>
  2721. #endif
  2722. #include "mytypes.h"
  2723.  
  2724. extern int PackRow();
  2725. /*
  2726.  * following definitions cut from ilbm.h file
  2727.  */
  2728. typedef UBYTE Masking;          /* Choice of masking technique.*/
  2729. #define mskNone                 0
  2730. #define mskHasMask              1
  2731. #define mskHasTransparentColor  2
  2732. #define mskLasso                3
  2733.  
  2734. typedef UBYTE Compression;      /* Choice of compression algorithm applied to
  2735.      * each row of the source and mask planes. "cmpByteRun1" is the byte run
  2736.      * encoding generated by Mac's PackBits. See Packer.h . */
  2737. #define cmpNone      0
  2738. #define cmpByteRun1  1
  2739.  
  2740. /* Aspect ratios: The proper fraction xAspect/yAspect represents the pixel
  2741.  * aspect ratio pixel_width/pixel_height.
  2742.  *
  2743.  * For the 4 Amiga display modes:
  2744.  *   320 x 200: 10/11  (these pixels are taller than they are wide)
  2745.  *   320 x 400: 20/11
  2746.  *   640 x 200:  5/11
  2747.  *   640 x 400: 10/11           */
  2748. #define x320x200Aspect 10
  2749. #define y320x200Aspect 11
  2750. #define x320x400Aspect 20
  2751. #define y320x400Aspect 11
  2752. #define x640x200Aspect  5
  2753. #define y640x200Aspect 11
  2754. #define x640x400Aspect 10
  2755. #define y640x400Aspect 11
  2756.  
  2757. /* A BitMapHeader is stored in a BMHD chunk. */
  2758. typedef struct {
  2759.     UWORD w, h;                 /* raster width & height in pixels */
  2760.     WORD  x, y;                 /* position for this image */
  2761.     UBYTE nPlanes;              /* # source bitplanes */
  2762.     Masking masking;            /* masking technique */
  2763.     Compression compression;    /* compression algoithm */
  2764.     UBYTE pad1;                 /* UNUSED.  For consistency, put 0 here.*/
  2765.     UWORD transparentColor;     /* transparent "color number" */
  2766.     UBYTE xAspect, yAspect;     /* aspect ratio, a rational number x/y */
  2767.     WORD  pageWidth, pageHeight;  /* source "page" size in pixels */
  2768.     } BitMapHeader;
  2769.  
  2770. /* RowBytes computes the number of bytes in a row, from the width in pixels.*/
  2771. #define RowBytes(w)   (((w) + 15) >> 4 << 1)
  2772.  
  2773.  
  2774.  
  2775. #define IDSIZE 4
  2776.  
  2777. WriteIlbm( filename, win, scrn,packflag )
  2778.     char *filename;
  2779.     struct NewWindow *win;
  2780.     struct NewScreen *scrn;
  2781.     bool packflag;
  2782. {
  2783.     FILE *ofile;
  2784.     long formpos; /* position of length following 'FORM' */
  2785.     long formsize;
  2786.     struct ViewPort *vp;
  2787.  
  2788.     ofile = fopen(filename,"w");
  2789.     if( !ofile ) {
  2790.         return;
  2791.     }
  2792.  
  2793.     fwrite("FORM", IDSIZE, 1, ofile);
  2794.     formpos = ftell( ofile );
  2795.     fwrite( &formsize, sizeof(formsize), 1, ofile); /* will be rewritten */
  2796.     fwrite( "ILBMBMHD", IDSIZE*2, 1, ofile );
  2797.  
  2798.     {
  2799.         BitMapHeader bmhdr;
  2800.         long bmhdrsize;
  2801.         static UBYTE xaspect[2][2]= { { x320x200Aspect, x320x400Aspect },
  2802.                                       { x640x200Aspect, x640x400Aspect }};
  2803.         static UBYTE yaspect[2][2]= { { y320x200Aspect, y320x400Aspect },
  2804.                                       { y640x200Aspect, y640x400Aspect }};
  2805.         int wx, wy;
  2806.  
  2807.         bmhdrsize = 20;
  2808.         fwrite( &bmhdrsize, sizeof(bmhdrsize), 1, ofile);
  2809.         bmhdr.x = bmhdr.y = 0;
  2810.         bmhdr.w = win->Width;
  2811.         bmhdr.h = win->Height;
  2812.         bmhdr.nPlanes = scrn->Depth;
  2813.         bmhdr.masking = mskNone;
  2814.         bmhdr.compression = packflag ?cmpByteRun1: cmpNone;
  2815.         bmhdr.pad1 = 0;
  2816.  
  2817.         wx = (scrn->Width == 320)? 0: 1;
  2818.         wy = (scrn->Height == 200)? 0: 1;
  2819.         bmhdr.xAspect = xaspect[wx][wy];
  2820.         bmhdr.yAspect = yaspect[wx][wy];
  2821.         bmhdr.pageHeight = win->Height;
  2822.         bmhdr.pageWidth = scrn->Width;
  2823.         bmhdr.transparentColor = 0;
  2824.         fwrite(&bmhdr, bmhdrsize, 1, ofile );
  2825.     }
  2826.  
  2827.     fwrite("CMAP",IDSIZE, 1, ofile);
  2828.     vp = &win->Screen->ViewPort;
  2829.     {
  2830.         long cmapsize;
  2831.         long i;
  2832.         UWORD value;
  2833.         UBYTE col[3];
  2834.         int numentries;
  2835.  
  2836.         numentries = (1<< scrn->Depth );
  2837.         cmapsize = numentries*3;
  2838.         fwrite( &cmapsize, sizeof(cmapsize), 1,ofile);
  2839.         for( i = 0; i < numentries; i++ ) {
  2840.               value = GetRGB4(vp->ColorMap, i);
  2841.               col[2] = (value & 0xf) << 4;        /* blue */
  2842.               col[1] = value & 0xf0; /* green */
  2843.               col[0] = (value & 0xf00) >> 4; /* red */
  2844.               fwrite(col, 3, 1, ofile);
  2845.         }
  2846.     }
  2847.  
  2848.     fwrite("CAMG", IDSIZE, 1, ofile);
  2849.     {
  2850.         long viewmode;
  2851.         long viewmodesize;
  2852.  
  2853.         viewmodesize = sizeof(viewmode);
  2854.         viewmode = scrn->ViewModes;
  2855.         fwrite(&viewmodesize, sizeof(viewmodesize), 1, ofile);
  2856.         fwrite(&viewmode, sizeof(viewmode), 1, ofile );
  2857.     }
  2858.  
  2859.     fwrite("BODY", IDSIZE,1, ofile);
  2860.     {
  2861.         struct BitMap *bm;
  2862.         long bodypos,
  2863.              bodysize;
  2864.         UBYTE *bmd[16]; /* assume as many as 16 bit planes :-) */
  2865.         int row;
  2866.         int plane;
  2867.         int rowlength; /* in bytes */
  2868.         char outbuff[200]; /* largest enough for a row 1600 bits wide */
  2869.  
  2870.         bodypos = ftell(ofile);
  2871.         fwrite( &bodysize, sizeof(bodysize), 1, ofile);
  2872.         bm = vp->RasInfo->BitMap;
  2873.         rowlength = RowBytes(scrn->Width);
  2874.  
  2875.         for( plane = 0; plane < scrn->Depth; plane++ ) {
  2876.             bmd[plane] = bm->Planes[plane] + rowlength * win->TopEdge;
  2877.         }
  2878.  
  2879.         /*
  2880.          * write actual bitplanes
  2881.          */
  2882.         for( row = 0; row < win->Height; row++ ) {
  2883.  
  2884.             for( plane = 0; plane < scrn->Depth; plane++ ) {
  2885.                 if( packflag ) {
  2886.                     int packedsize;
  2887.  
  2888.                     packedsize = PackRow(bmd[plane],outbuff, rowlength );
  2889.                     fwrite(outbuff, packedsize, 1, ofile);
  2890.                 }
  2891.                 else {
  2892.                     fwrite(bmd[plane], rowlength, 1, ofile );
  2893.                 }
  2894.                 bmd[plane] += rowlength;
  2895.             }
  2896.         }
  2897.         bodysize = ftell(ofile) -( bodypos + 4);
  2898.         /*
  2899.          * fill out body to make even
  2900.          */
  2901.         if( bodysize & 1 ) {
  2902.             fputc(0,ofile);
  2903.             bodysize++;
  2904.         }
  2905.         formsize = ftell(ofile) -( formpos + 4);
  2906.  
  2907.         fseek( ofile, bodypos, 0L );
  2908.         fwrite( &bodysize, sizeof(bodysize), 1, ofile);
  2909.     }
  2910.  
  2911.     fseek( ofile, formpos, 0L );
  2912.     fwrite( &formsize, sizeof(formsize), 1, ofile);
  2913.  
  2914.     fclose(ofile);
  2915. }
  2916. \Rogue\Monster\
  2917. else
  2918.   echo "will not over write ./writeilbm.c"
  2919. fi
  2920. echo "Finished archive 1 of 3"
  2921. # if you want to concatenate archives, remove anything after this line
  2922. exit
  2923. -- 
  2924. Bob Page, U of Lowell CS Dept.  page@swan.ulowell.edu  ulowell!page
  2925. "I can't tell the difference between ABC News and Hill Street Blues" -Bono
  2926.